一,命名空间
1.何为命名空间
在C++中,变量、函数和类的名称都将作用于全局作用域中,可能会导致很多命名冲突。使用命名空间的目的就是对标识符和名称进行本地化,以避免命名冲突或名字污染。定义命名空间,需要使用到 namespace 关键字,后面跟命名空间的名字,然后接一对 {}即可, {}中即为命名空间的成员。命名空间将全局作用域分成不同的部分,不同命名空间中的标识符可以同名而不会发生冲突,命名空间可以发生嵌套,全局作用域也叫默认命名空间。
2.命名空间的使用
故主要作用是为了防止名字冲突,例如包含某个头文件展开后,自己定义的变量与之冲突就会报错,想要避免这种错误,我们会命名一片空间放入其中。
例如这种情况
#include<iostream> #include<stdlib.h> using namespace std; int rand = 0; int mian() { cout << rand << endl; return 0; }
namespace myspace { int rand = 0; }
添加空间之后了,相当于给定了附属关系,现在有两个rand,一个是函数里的,一个就使myspace里的,命名就无法冲突了。
命名空间中可以定义变量,函数,类型。
namespace myspace { int rand = 0; int ADD(int x,int y) { return x + y; } struct intdata { int data=1; }; }
4.::作用域限定符
其次通过作用于限定符可以表明某个成员的属于关系,格式为空间名::空间成员 ,
namespace myspace { int rand = 0; int ADD(int x,int y) { return x + y; } struct intdata { int data; }; } int main() { cout << myspace::rand << endl; cout << myspace::ADD(1,2) << endl; struct myspace::intdata a; a.data = 2; cout << a.data << endl; return 0; }
3.命名空间的展开
为了防止冲突,定义在命名空间后,由于多次频繁使用这个变量,每次加作用于限定符很麻烦,于是我们可以展开命名空间,编译器在调用时可以直接访问空间中的成员。
全局展开:
格式 using namespace 空间名;
但这种写法人存在弊端,因为命名冲突我们才利用空间分隔开,但若存在冲突的情况,直接展开的话,编译器还是不知道应该先用哪一个。
namespace myspace { int rand = 0; int ADD(int x,int y) { return x + y; } struct intdata { int data; }; } using namespace myspace; int main() { cout << rand << endl;//cout << myspace::rand << endl; cout << ADD(1,2) << endl; struct intdata a; a.data = 2; cout << a.data << endl; return 0; }
这里的rand 还是会报错,编译器选择冲突,此时还是要利用作用域限定符表明我是这个空间里的。 因此展开命名空间比较危险,我们一般还是需要作用域限定符比较安全。
局部展开:
其次除了全局展开外,我们也可以利用局部展开,格式 using 空间名:: 成员名;
namespace myspace { int ADD(int x,int y) { return x + y; } struct intdata { int data; }; } using myspace::ADD; using myspace::intdata; int main() { cout << ADD(1,2) << endl; struct intdata a; a.data = 2; cout << a.data << endl; return 0; }
局部展开与全局展开也是有同样的风险。
其次我们经常写的这两行就可以得到解释
#include<iostream> using namespace std;
首先std是c++标准库中的命名空间,包含输出输入流头文件以后,全局展开std这个空间中的cout,cin等。
当然我们也可以不展开,利用作用域限定符有依然可以。
4.嵌套命名空间
命名空间可以嵌套使用,一般我们也就嵌套一两层,
namespace father { int x = 1; namespace son { int y = 2; } } int main() { cout << father::x << " " << father::son::y << endl; return 0; }
其次,相同的命名空间会自动合并在一起。
二,缺省参数与函数重载
1.什么是缺省参数
缺省参数是c++对于函数声明或定义时伟函数的参数提供一哥缺省值,在调用函数时如果没有指定实参,那么函数会调用提供的缺省参数。例如:
int ADD(int x=1,int y=2) { return x + y; } int main() { cout << ADD() << endl;//3 cout << ADD(2,4) << endl;//6 return 0; }
如以上ADD函数设置了缺省参数,在未给有实参时,我们 会默认调用设值得缺省参数,若有实参,先调实参。
缺省参数分为全缺省和部分缺省,即所给定的实参的个数是否满足形参的个数。
int ADD(int x=1,int y=2) { return x + y; } int main() { //传参从左往右 cout << ADD() << endl;//全缺省 3 cout << ADD(2) << endl;//部分缺省 4 cout << ADD(2,3) << endl;//无缺省 5 cout << ADD(, 3) << endl;//错误写法 return 0; }
2.什么是函数重载
函数重载是指在同一作用域内,可以有一组具有相同函数名,不同参数列表(参数个数、类型、顺序)的函数,这组函数被称为重载函数。(注意无返回类型)
当调用一个重载函数时,编译器通过比较传递给函数的参数类型和数量来确定要调用哪个函数。如果找不到匹配的函数,则编译器会发出错误消息。
通俗的来说,利用函数重载可以做到,相同的函数名,但可以写多个函数,实现多种操作。
int ADD(int x,int y) { return x + y; } int ADD(int x) { return x; } double ADD(double x, double y) { return x + y; } int main() { cout << ADD(1) << endl;// 1 cout << ADD(1,2) << endl;// 3 cout << ADD(1.0,2.0) << endl;// 3 return 0; }
根据参数的个数 ,类型,顺序,调用实参对应的函数,一般重载函数的大部分功能是相同的。
3.两者的冲突
之后我们会发现,同时存在函数重载和缺省参数,此时会出现冲突/例如:
int ADD(int x,int y) { return x + y; } int ADD(int x) { return x; } int ADD(int x=0, int y) { return x + y; } int main() { cout << ADD(1) << endl; cout << ADD(1,2) << endl; return 0; }
此时编译器调用函数时就会发生冲突不知道是应该调用缺省参数,还是重载函数。