C++类和对象
缺省参数
- 半缺省参数必须从右往左依次给出,不能间隔着给
- 缺省参数在函数声明的时候给出,不能声明定义同时给
- 缺省值必须是常量或者全局变量
引用
- 在使用引用时,权限可以平移和缩小,不能放大
- 引用定义时必须初始化
- 引用一旦引用一个实体就不能引用其他实体
1 | int main() |
内联函数
用inline修饰的函数,inline只是一种建议,比较长的函数、递归函数等就算被定义为inline也会被编译器忽略
在调用内联函数的地方进行展开,不需要建立函数栈帧,提升程序运行效率
this指针
- this指针被const修饰不能被修改,但是this指针指向的内容可以被修改
- 只能在“成员函数”的内部使用
- this指针可以在类里面被引用,但是不能在函数形参里面定义,这个编译器会自动生成
练练手:
1 | // 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行 |
答案:C
在 p->Print() 这一步,可能会觉得是访问了空指针,但是实际上只是把 this 指针赋为空,但是 Print 函数是直接打印的,并没有对 this 指针进行访问,所以不会运行崩溃
1 | // 1.下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行 |
答案:B
因为打印的是_a,实际上就是this->_a,所以对this指针进行了访问,导致运行崩溃
默认成员函数
构造函数
- 构造函数不是开空间创造对象,而是初始化
- 函数名和类名相同
- 无返回值,不需要写void
- 对象实例化的时候编译器自动调用构造函数
- 构造函数可以重载
- 编译器自动生成的构造函数,对于内置类型成员变量(int, char, double...)不做处理,对于自定义类型成员变量(class, struct,...)会调用它的无参构造
- 如果类中没有显示定义构造函数,编译器会自动生成一个无参的构造函数,一旦用户显示定义编译器将不再生成
析构函数
- 析构函数不是对对象本身的销毁,而是完成对象中资源清理工作
- 函数名是在类名前面加上~
- 在对象声明周期结束的时候自动调用
- 析构函数不能重载
拷贝构造
- 参数只有一个且必须是类类型对象的引用,使用传值的方式会引发无穷递归,正确形式:Date (const Date& d)
- 若未显示定义,则编译器会默认生成,但是只完成字节序的拷贝,即浅拷贝
- 如果类中没有涉及资源申请的时候,写不写拷贝构造都可以;但是如果涉及到资源申请,就必须写拷贝构造,否则会出现两个不同的对象指向同一块空间
赋值运算符重载
- 函数名是operate后面加需要重载的运算符
- ".* " "::" "sizeof" "?:" "." 这5个运算符不能重载
- 赋值运算符重载格式:
- 参数类型:const T&
- 返回值类型:T&,有返回值是为了连续赋值
- 检测是否是自己给自己赋值
- 返回*this,要符合连续赋值的定义
1 | Date& operator=(const Date& d) |
- 赋值运算符重载只能重载成类的成员函数,不能重载成全局函数
- 同拷贝构造一样,默认的赋值运算符重载只完成浅拷贝
const成员
const修饰的“成员函数”成为const成员函数,实际上修饰的是this指针,表明在该成员函数中不能对类中的任何成员进行修改
初始化列表
以一个冒号开始,接着是以一个逗号分隔的数据成员列表,每个“成员变量”后面跟一个放在括号中的初始值或者表达式
1 | class Date |
- 每个成员变量在初始化列表中只能出现一次,初始化只能初始化一次
- 类中包含以下成员,必须放在初始化列表中初始化
- 引用成员变量
- const成员变量
- 自定义类型成员(且该类没有默认构造函数时)
- 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中初始化的顺序无关
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 眨眼的小星星!