C++对C的扩充

C++语言是对C的一种扩充和优化,同时引入了OOP(面向对象编程)的思想。所以,建议掌握了C语言的基本使用和语法再进一步学习C++。同时了解C++与C语言的区别。


其实C++对C的扩充很多,在这里描述一些常用的点。剩余的琐碎知识会慢慢的说到。

请看一下代码

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
//using namespace std; 
int atk = 200; 
void test() { 
    int atk = 100;
    std::cout<<"test中的atk<< atk << std::endl;
    std::cout<<"全局中的atk<< ::atk << std::endl;
}
int main()
{
    test();
    return 0;
}

这段代码会一一讲解
#define \_CRT\_SECURE\_NO\_WARNINGS
这是一个宏,如果是使用vs系列的编译器,在程序编译的时候可能出现C4996错误,通过这个宏基本可以解决这个问题

之后会涉及以下三个知识点:

命名空间(namespace)

using namespace std;
这是一句十分常见的代码(但并不推荐这么使用)
其中std是标准命名空间,如果不写这条语句 会无法使用诸如cout,cin 等等。因为C++标准的标识符都被记录在std的命名空间中。除了以上的语句,我们还可以使用作用域运算符(::)来单独的使用某一个标识符:
std::cout<<"hello World!<<std::endl;"
其实更加推荐以上的写法。
在C++中,程序员除了可以使用系统提供的命名空间。还可以自己写命名空间,而命名空间的作用就是 消除名称的冲突。
以下是namespace的使用:

//test1
#include <iostream>
using namespace std;
namespace test1
{
    void test()
    {
        cout<<"这里是test1"<<endl;
    }
  
}
//test2
namespace test2
{
    void test()
    {
        cout<<"这里是test2"<<endl;
    }
}

//main
int main()
{
    test1::test();
    test2::test();
    return 0;
}

结果可想而知:
image.png
除此之外namespace还有以下几点:

1.namespace下可以放函数,变量,类,结构体

2.namespace必须作用到全局作用域中。

3.nameapace可以嵌套。(如果是嵌套的话需要连续使用作用域运算符)

4.namespace是开放的,可以随时添加内容

namespace A
{
    ...
}

...

namespace A
{
    ...
}

这样写的话这两个A是可以连接起来,而不是覆盖。
5.可以有无名(匿名)的命名空间。相当于一个static只能在当前文件内使用(基本没什么用,知道有这么回事就行了)

6.命名空间可以有别名。如果起的第一个名字太长了,不方便使用。可以用一个新的名字(仔细想想好像也没什么用,毕竟起名是所有程序员不得不去面对的一个难题)

using声明和using编译指令

using声明
namespace test
{
    int a = 10;
}
void test1()
{
    using test::a;//using 声明
    std::cout<<a<<std::endl;
}
using 编译指令

using namespace test;//using 编译声明

[注]编译器是有就近原则的。using声明会与就近原则产生二义性,using编译指令会服从就近原则;因为using编译指令只是声明了命名空间,不一定非要使用。而using声明就是声明nanespace里面的一个标识符,这样自然会冲突。

#include <iostream>
using namespace std;

namespace A
{
    int aa = 10;
}
//using声明:
void test01()
{
    int aa = 20;
    using A::aa;
    //写下以上这行代码,编译器会报错
    //using声明后,AtkofQOP即是在Dota2命名空间下的
    //同时编译器又是有就近原则的,
    //所以产生了二义性
    
    cout<<aa<<endl;
}
namespace B
{
    int aa = 30;
}
//using 编译指令
void test02()
{
      int aa = 20;
      //使用using 编译指令
  using namespace A;//打开A的命名空间,不一定会去使用,依旧是服从就近原则!
      cout<<aa<<endl;
      //输出内容是20
      //如果注释int aa = 20;
      //同时打上 using namespace B,我们在输出aa时,编译器就无法辨认了
      //如果使用(打开)的命名空间过多,注意一定要使用作用域运算符指定具体的位置
      //这就是为啥不推荐直接写using namespace std;的原因,用的多了会引起不必要的混乱
      
}

作用域运算符(::)

在一开始给出的例子中,我们看到了::的作用(指定全局,其实就是::前面什么都没有,就默认是全局了)。
结合namespace也不难理解::的作用。就是作用域是指定,这个作用域不仅是namespace 还包括后面类的成员变量和成员函数。只要是需要指定变量或者函数的所属,都会用到作用域运算符。


Horizon
3 声望1 粉丝

今日潜修默进,是为来日天下行走