- 一、拷贝构造函数
- 1、何时使用到拷贝
- 2、默认拷贝构造的工作
- 3、编译器何时自动生成拷贝构造
- 3.1 重新设定virtual table指针
- 3.2 处理virtual base class subobject
拷贝分类:拷贝构造和拷贝赋值操作符 - 拷贝构造:被初始化; - 拷贝赋值操作符:被指定; 产生拷贝动作: - 当以一个对象的内容作为另一个对象的初值时; - 当对象被当作参数传递时; - 当函数返回一个对象时 一般会导致一个临时类对象的产生;
拷贝构造形式
class A{
public:
A(const A& a);
A(const A& a, int x=0……) // 如果要带参数,则必须指定默认参数
};
2、默认拷贝构造的工作
拷贝构造在数据成员和类成员之间有区分: - 类成员会递归进行memberwise initialization,其他的数据成员直接拷贝;
class Word {
private:
String _word; // 类成员
int _occurs; // 普通成员
};
3、编译器何时自动生成拷贝构造
何时不展现出bitwise copy semantics
没有bitwise copy semantics时,编译器将要合成拷贝构造 - 当类内含一个成员类,而成员类中声明一个拷贝构造; - 当类继承一个基类,而该基类存在一个拷贝构造时; - - 以上两种情况必须将后者的拷贝构造插入到类中的拷贝构造; - 当类声明一个或多个虚函数; - 当类派生一个继承串链,其中一个或多个虚基类时; 以上所有情况需要编译器合成拷贝构造函数;3.1 重新设定virtual table指针
当类中出现虚函数即会执行该操作: - 增加vtbl,内含每一个有作用的虚函数地址; - 一个指向vtbl的vptr,安插在每一个类对象内; 当使用拷贝构造发生在带虚函数的类上时,该vptr的初始化将会交给它;
class ZooAnimal {
public:
ZooAnimal();
virtual ~ZooAnimal();
virtual void animate();
virtual void draw();
};
class Bear : public ZooAnimal {
public:
Bear();
void animate();
void draw();
virtual void dance();
};
void test() {
Bear yogi;
Bear winnie = yogi;
ZooAnimal franny = yogi; // 会被切割
}
合成的ZooAnimal拷贝构造会显示设定obj的vptr指向ZooAnimal class 的vtbl,而不是从右边的类对象将其vptr拷贝过来;3.2 处理virtual base class subobject
在虚继承中,编译器必须确保子类对象中的虚基类子对象位置在执行期就准备好,而bitwise copy semantics会破坏该位置,故编译器需要合成拷贝构造且 在内部做出仲裁;



