目录
一、C++和C的区别
面向过程语言:C ----->重视求解过程
面向对象语言:C++ ------>重视求解的方法
C++在C的基础上引入了更多的元素,例如类,类的私密性要比C中的结构体更加优秀,引用,重载,命名空间,以及STL库,模板编程和更多的函数,在面向对象的编程上更加高效。C语言的优势则是更加底层,编译速度会更快,在编写内核时大多数都是C语言去写。
在C++中,命名空间(Namespace)是一种组织代码的方式,主要用于解决全局变量、函数或类的命名冲突问题。命名空间提供了一种封装机制,允许开发者将相关的类、函数、变量等放在一个逻辑上封闭的区域中,这样相同的名字在不同的命名空间中可以共存,而不会相互干扰。
二、命名空间
用于解决命名冲突/明明污染问题
【1】接触到的第一个命名空间
标准命名空间std:cout endl cin
如果代码中没有using namespace std,cout和endl会报错
编辑
【2】定义
命名空间中可以存放,标识符:变量名、函数名、结构体名、枚举名
namespace 命名空间名
{
定义变量;
函数声明;
结构体名;
···
};
命名空间中,只能存放函数的声明,不能放函数的定义
【3】使用命名空间中的标识符
域限定符 ::
i)全局导入整体命名空间
using namespce 命名空间名;
在该行下的所有代码,都可以使用A中的所有标识符
ii)全局导入部分标识符
using 命名空间名::标识符名;
using A::a; ---->后面的代码都可以使用命名空间A中的标识符a
在该行下的所有代码,可以使用导入的指定的标识符
iii)局部导入标识符
在哪个位置使用,使用时直接通过域标识符来进行限定
include <iostream> using namespace std; namespace A { int a=90; char c='x'; float p=3.14; void fun(); }; int main() { A::fun(); cout << A::a << endl; return 0; }
include <iostream> using namespace std; namespace A { int a=90; char c='x'; float p=3.14; void fun(); }; //命名空间内声明fun函数,在命名空间外定义fun函数,需要给函数名加域限定符:: void A::fun() { cout << "fun函数" << endl; } //全局导入命名空间中的所有标识符 //using namespace A; //全局导入命名空间中的部分标识符 /*using A::fun; using A::a; */ int main() { A::fun(); cout << A::a << endl; return 0; }
【4】命名冲突问题*
main.cpp:27:5: error: call to 'fun' is ambiguous
main.cpp:8:10: note: candidate function
main.cpp:12:6: note: candidate function
i)两个命名空间中标识符冲突
- 两个命名空间中有同名成员
- 同时可以访问两个命名空间中的成员
怎么解决:
- 命名空间名+域限定符
- 只导入一个命名空间,代码就只能访问导入的命名空间中的标识符
ii)局部变量和命名空间中标识符冲突
代码不会报错,但是只能默认访问局部变量
想要访问命名空间中的标识符:命名空间名+域限定符
namespace A { int a=90; char c='x'; float p=3.14; void fun(); }; int main() { //在使用的位置使用域限定符 A::fun(); int a=100; cout << A::a << endl; cout << "B中的a=" << B::a << endl; return 0; }
iii)全局变量和命名空间标识符冲突
访问全局变量:只在标识符前加域限定符 ::a ----->访问全局变量a
访问命名空间中标识符:命名空间名+域限定符
include <iostream> using namespace std; int a=1000; //定义了一个全局变量a namespace A { int a=90; char c='x'; float p=3.14; void fun(); }; int main() { //在使用的位置使用域限定符 A::fun(); cout << ::a << endl; //加上域限定符访问全局变量的a, //因为全局变量,默认在匿名空间中 cout << "B中的a=" << B::a << endl; return 0; }
【5】匿名空间
没有名字的命名空间,就是匿名空间
匿名空间中的标识符的访问方式:
::标识符名
注意:匿名空间中的标识符尽量不要和全局变量冲突
include <iostream> using namespace std; int a=1000; //定义了一个全局变量a namespace B { int a=130; } //命名空间内声明fun函数,在命名空间外定义fun函数,需要给函数名加域限定符:: void A::fun() { cout << "fun函数" << endl; } //全局导入命名空间中的所有标识符 using namespace A; //using namespace B; //匿名空间,尽量不要使用匿名空间 namespace { int a = 2000; char c; } int main() { //在使用的位置使用域限定符 A::fun(); cout << ::a << endl; //加上域限定符访问全局变量的a, //因为全局变量,默认在匿名空间中 cout << "B中的a=" << B::a << endl; return 0; }
【6】嵌套的命名空间
一个命名空间定义在另一个命名空间内
访问时需要逐层查找
include <iostream> using namespace std; namespace A1 { int num1 = 10; int num2 = 30; namespace A2 { int num1=1; int num2=90; int x = 7; } } using namespace A1; using namespace A1::A2; int main() { //想要访问A2中的num1 //由于A2是包含在A1内的,想要访问到A2需要一层一层访问 cout << A1::A2::num1 << endl; //cout << num2 << endl; 一定构成命名冲突问题 cout << A1::num2 << endl; return 0; }
【7】给命名空间重命名
namespace 新的名字 = 旧的名字;
include <iostream> using namespace std; namespace A1 { int num1 = 10; int num2 = 30; namespace A2 { int num1=1; int num2=90; int x = 7; } } using namespace A1; using namespace A1::A2; int main() { //想要访问A2中的num1 //由于A2是包含在A1内的,想要访问到A2需要一层一层访问 cout << A1::A2::num1 << endl; //cout << num2 << endl; 一定构成命名冲突问题 cout << A1::num2 << endl; return 0; }
【8】using的另一种用法
using还可以用于类型重定义
C++ 11标准才能使用using实现重定义
typedef int arr[5];<===>arr相当于int [5]
typedef int p; <===>p后面就相当于int
include <iostream> using namespace std; namespace p = A1; //把命名空间A1重命名为p,后面既可以使用A1访问也可以使用p访问 using namespace A1; using namespace A1::A2; int main() { //使用suing把int,重命名为INT,后面使用哪一个都可以定义整形变量 using INT = int; INT a = 90; cout << a << endl; cout << sizeof(a) << endl; return 0; }