函数调用有时空开销,执行函数前要将实参、局部变量、返回地址及若干寄存器压入栈中,再执行函数体中的代码,函数执行完还要清理现场,将之前压入栈中的数据出栈。在编译时将函数调用处用函数体替换,类似C中的宏展开,内联函数。缺点是编译后的程序存在多份相同的函数拷贝,使函数体积增大。
内联函数替换带参数的宏,内联函数可定义在头文件,并且头文件多次引用也不会引发重复定义错误。
内联函数在编译时会将函数调用处用函数体替换,编译完成后函数就不存在了,所以链接时不会引发重复定义错误。和宏很像,宏在预处理时被展开,编译时不存在了,内联函数更像是编译期间的宏。
推荐内联函数不应有声明,在函数定义时加上inline关键字。若将内联函数的声明(.h)和定义(.cpp)分散到不同文件中会出错。
函数是一段可重复使用的代码,它位于虚拟地址空间中的代码区,也占用可执行文件的体积,内联函数的代码在编译后就被消除了,不存在于虚拟地址空间中,没法重复使用。
C++中默认参数只能放在形参列表的最后,一旦为某个形参指定了默认值,那么它后面的所有形参都必须有默认值。
C++代码在编译时会根据参数列表对函数进行重命名,发送函数调用时,编译器会根据传入的实参去逐个匹配,以选择对应的函数,若失败会报错,即重载决议。
编译器从高到低搜索重载函数,首先精确匹配、然后是类型提升、最后是类型转换。
类
类体内定义的成员函数会自动成为内联函数,建议类内声明函数,类外定义函数。
类内成员无论声明成public、private、protected均可以互相访问。什么标识符都不写默认为private。
声明为protcted的成员在类外也无法通过对象访问,但是在它的派生类中可以访问。
类不占用内存空间,不存在与编译后的可执行文件中,对象是实实在在的数据,需要内存来存储。
编译器会将成员变量和成员函数分开存储;分别为每个对象的成员变量分配内存,但所有对象共享同一段函数代码。成员变量在堆区或者栈区存储,成员函数在代码区分配内存。对象的大小仅和成员变量有关,与成员函数无关。
C++中函数编译时会根据它所在的命名空间、所属的类、参数列表(也叫函数签名)等信息基础重命名,该过程叫名字编码(Name Manging)是可逆的过程。只声明不定义函数,编译器会报错,从报错信息可看到编译器新生成的函数名。
成员函数的调用
类中的成员函数最终被编译成与对象无关的全局函数,若函数体没有成员变量,不用对函数做任何处理,直接调用即可。
C++规定编译成员函数时要额外添加一个参数,把当前对象的指针传递进去,通过指针来访问成员变量。通过传递对象指针完成了成员函数与成员变量的关联。
一旦用户自定义了构造函数,编译器不会再生成构造函数。
构造函数初始