C++的域作用限定符和命名空间
1.C++域作用符
::是域作用限定符 例如::a;域作用限定符前面是空表示全局。
class A{ public: A(int x){};//构造函数 ~A(){};//析构函数 private: int _a;//私有成员变量 }; A::A(int x){//这里的::就是域作用限定符 _a = x; }
域作用限定符提供了不同作用域内变量名可以相同的机制
2.C++命名空间
命名空间用来定义域,作用是名字隔离,解决命名冲突的问题。C++所有标准库的东西都放在std命名空间中。
using namespace std;严格而言并不是一种好的方式,最好指定使用的域空间
而且指定命名空间域是规范的写法。
C++的重载
函数重载:
C++函数重载的定义:
在同一作用域内,一组函数的函数名相同,参数列表不同(参数个数不同/参数类型不同),返回值可同可不同
C++是如何支持重载的?先看下面的栗子
void f1(char c){} void f1(int i){}
\>>_Z2f1c 函数名重载,2是字节数
\>>_Z4f1i
C++函数重载的原理:
编译器在编译.cpp文件中当前使用的作用域里的同名函数使,根据函数形参类型和顺序会对函数进行重命名(一般而言,不同的编译器在编译时对函数的重命名标准不一样),但是总的来说,他们都把文件中的同一个函数名进行了重命名;
VS编译器:根据返回值类型+形参类型和顺序,起关键作用的是形参类型和顺序
g++中:根据函数名字的字符数+形参类型和顺序的规则重命名记录在符号表中;从而产生不同的函数名,当函数被调用时,就根据这个记录的结果去寻找符合要求的函数名调用
程序编译
既然提到了C++的编译,就谈谈程序编译的几个阶段:
test.cpp test.h main.cpp
1.预处理 ->展开头文件、宏替换、条件编译、去注释
test.i main.i
2.编译->检查语法、生成汇编代码
test.s main.s
3.汇编->转成二进制的机器码
test.o main.o
4.链接
a.out
<1>预处理阶段:预处理阶段会将程序所包含的头文件展开,也就是.h文件,会直接展开,然后将代码里所有的宏定义都替换掉,在处理条件编译语句,最后将代码里的注释去掉
<2>预处理结束后就是编译阶段:编译阶段主要是检查语法,代码的规范性,是否有语法错误等,以此确定代码实际要做的工作,在检查无误之后,将代码翻译成汇编代码,也就是现在的代码已经全部是汇编语言了
<3>汇编阶段:汇编阶段是把编译期间生成的.s文件转换为目标文件,也就是.o文件,这里的目标文件全都是二进制目标代码,是给机器看的。
<4>链接阶段:所有的文件编译完成生成目标文件之后,就要进行链接,链接就是把代码中用到的库啊,函数啊,都要拼接起来,如果你在代码中使用到的函数编译器没有找到,那么就会报错。
C++的缺省参数
在C语言中,函数没有指定参数列表,默认可以接收任意多个参数,但在C++中,因为有着严格的类型检测,没有参数列表的函数,默认为void,不会接收任何参数,而缺省参数就是声明或者定义函数时为函数的参数指定一个默认值。在调用函数时,如果没有指定实参则会使用默认的实参,否则使用指定的实参,要注意的是,缺省参数,只能从右往左缺省。
临时变量的性质
临时变量具有常性 const
const int& g = 10;
临时变量较小时,一般在寄存器(windows下在EAX寄存器)。
如果比较大,在生成汇编时在main函数的栈桢提前开好了空间
出了作用域还在,用引用返回减少消耗
出了作用域不在,用传值返回