目录
4.1 类与对象概述
4.2 类定义后面为什么一定要加分号
与类相对应的就是结构体和联合体,后面都得跟分号。这个地方的理由可以把类当做int类型来看,如果类型后面不加分号,那编译器会当做这句话没结束,然后和后面的语句连接起来。所以造成错误。
4.3 关于初始化列表
首先解释下前面提到的为什么在类的定义中,不能直接在类体内初始化数据。因为那属于类的声明,也就是根本还没有内存申请出来。所以不能在类内做普通变量的初始化。 只能在构造函数中初始化。
有三类数据必须使用初始化列表:常量,引用,其他类对象(这个地方主要是,B分配空间的时候就会掉A的默认构造函数,如果A没有默认构造函数就会报错)
具体例子见P151
4.4 对象的生成方式
4.5 关于临时对象
4.6 关于点操作符
一般而言,在外面,我们是不能访问一个类B的私有变量的。 那有个地方比较特殊:
1 - 在类B的成员函数中(不管是普通函数还是静态函数),如果该成员函数的形参是类B的对象,这个函数中就可以访问这个形参的私有变量
2 - 友元函数
4.7 嵌套类与局部类
- 嵌套类:是在一个类A里面又声明了另一个类B;这个B的定义或者实现,可以在类A里面写,也可以拿到类A外面实现。具体案例见164;类A和类B其实没有任何关系。只不过就是类B的声明域小了。只有A能用(如果B是private,如果是public外面的也可以用)
- 局部类:声明类在函数中声明,定义必须在类内实现(很少使用)
4.8 对象之间的比较
具体见P169
4.9 类的静态成员的定义和使用
类的静态成员的初始化:
- 静态常量:既可以在类内初始化,也可以在类外初始化
- 普通静态变量:必须在类外初始化,而且只能初始化一次
- 总结:不管是什么只要是静态的,就在类外初始化肯定没错。类外初始化的时候 不用再加static
4.10类的设计与实现规范
4.11 抽象类与纯虚函数
4.12 类对象的内存布局
具体见P182
一般类内的存储顺序是:虚函数表+基类数据 + 派生类数据
类的长度:只由类的数据成员构成(不包含静态数据和函数成员(因为这两个都是所有类实例共用的))
在基类和派生类中的this指针相同吗?
实际是不相同的,理论上基类的this是包含在派生类内存中的,见上面类内存储,也就是地址有偏移。具体见P186
4.13 为什么说最好将基类的析构函数定义为虚函数
案例:如果用派生类去初始化基类的指针,在delete基类指针的时候,调用的是基类的析构函数而不是派生类的析构函数,所有可能造成内存泄漏。所有需要把基类的析构函数定义为虚函数,这样就能根据虚函数表调用到正确的析构函数。
4.14 对象数据成员的初始值
如果在声明类的时候,不显示定义任何构造函数,则编译器会生成一个默认的构造函数,而这个函数实际上什么都没有干。
具体案例见P190
4.15 对象产生和销毁的顺序
4.16 关于拷贝构造函数
如果没有显示定义拷贝构造函数,编译器生成的拷贝构造函数,默认是做的浅拷贝。
一般什么时候需要显示定义拷贝构造函数呢?
- 需要深拷贝
- 利用已知对象生成和原来并不是完全一样的对象,有一些改动
拷贝构造和赋值函数的区别:拷贝构造属于构造函数,也就是无中生有;赋值函数是operator=(),把同类对象赋值给另一个已经存在的对象