命名空间
C++中的命名空间namespace wind(有点像定义一个结构体,把变量名都放进去) 可以有效的防止自己定义函数或变量名时与库中的函数名重复,防止命名冲突(自己的命名和库中冲突,会产生二义性,所以创造一个围墙,将自己定义的各种名字放进去)在使用时wind::变量名。::是域作用限定符,围墙名字::变量名
C语言如果命名冲突了,只能换名字。而C++可以自行创建namespace这个域,用::指定域就可以让编译器在编译的时候在这个域里面找名字,如果不指定域,编译器就会在全局搜索
如何理解命名空间:类似于一个包围起来的私密空间。可以将变量名,函数名,结构体名都放进去,在这个私密空间中,这些名字可以与库中的函数名相同而不会发生冲突。当需要调用命名空间中的名字时,使用wind::名字,如果只用名字就会找不到,只在全局中找是找不到的,必须使用::,才能获得这个命名空间的授权,或者using namespace wind将这个空间完全展开(开放空间特别不安全,在工程中不能使用),因为有保护。
命名空间可以套娃,就是在一个命名空间里面再定义一个命名空间,调用时,使用两个:: ::
using namespace std 这一行的意思授权C++标准库的命名空间,使我自己定义的名字不会和库里面的名字冲突。和包含头文件不一样,头文件展开是将库的内容拷贝过来,std是C++标准库,using namespace相当于一个授权,将这个标准库展开,就可以去库里面寻找,就可以使用里面的名字,展开命名空间是很危险的行为。 也可以不把std命名空间展开,之后使用标准库里面的名字时,std::cin std::cout ,其实这是更推荐的写法
在C++中,使用名字的时候,无论是自己定义的名字,还是标准库里面的名字,无论是变量名还是函数名等等,所有名字都必须使用域作用限定符来标识域,否则就会报错标识符未声明。如下图,是自己创建的bit域和fei域,域里面可以放声明,也可以放定义,变量函数结构体等等都可以放进去
命名空间可以自动合并,在多个文件中使用同一个命名空间是可以的,作为头文件包含进去后,里面的内容是可以共用的,会发生自动合并成一个命名空间
缺省参数
是在函数定义时,对某些参数做一个备胎处理(就是给某些参数的一个赋值,之后在函数调用的时候如果没有给这些参数的值,就默认启用备胎,如果给了新值,就使用新的)
全缺省,函数中的形参全部都是默认值,一个参数都不用传
比如void Add(int x=1,int y=2,int z=3)。函数调用时,Add()就是不传参直接全部默认值,Add(13),就是相当于只传参第一个参数,后面全默认值。Add(13,2)就是分别给第一个第二个形参传参,Add(13,2,3),就是三个形参都传。以上4种写法都可以
半缺省:函数中的形参有一部分有缺省值
比如void Add(int x,int y,int z)。缺省值只能依次从右边的形参开始给,比如这个Add函数是3个形参,如果写成半缺省函数,只能是这两种写法,void Add(int x,int y=1,int z=2),void Add(int x,int y,int z=2)。传参的时候,如果是一个实参就是传给第一个形参,如果是两个实参就是传给第一个和第二个形参
声明和定义分离的时候,不能在声明处和定义处同时给缺省值,应该在声明处给,不在定义处给
static可以影响链接属性,全局变量可以在所有地方都可见,意思就是它进入符号表,static可以让它只在当前文件可见。从外部链接改成内部链接。
函数重载
一个函数有几个不同的含义。C++允许在同一作用域声明几个功能相似的同名函数,同名函数的形参列表(参数个数或类型或顺序)必须不同。返回值不同不构成重载。
函数重载的意义是使用功能相似的函数的时候更方便,就像使用同一个函数一样
C++为什么支持函数重载:
在编译过程中,生成符号表,符号表中包含函数名和地址或变量名和地址。C直接用函数名在符号表中找,C语言的符号表中就是函数名,所以无法区分。C++中有函数名修饰规则(把类型带入名字),可以找到函数的地址。只有声明没有定义就会找不到,没有定义就没有生成一堆指令,就没有地址,所以在符号表中找这个函数名就会找不到。函数的地址本质是第一句指令的地址,前面会加一个跳转指令。函数被编译完了的本质是一串指令,第一个指令就是他的地址,他的前面可能会被封起来,需要跳转两次才能跳过来,跳过来就可以执行函数,建立栈帧