在上一篇中提到编译器会在需要的时候合成一个拷贝构造函数,有以下四种情况如果没有提供显示的拷贝构造函数,编译器会合成一个构造函数,来完成一些必要的操作:
1.在一个类中,有一个类成员变量,且这个这个成员变量的类中提供了一个拷贝构造函数(此处的构造函数可以是显式声明的也可以是编译器合成的),这时候会需要编译器来合成一个拷贝构造函数,以便调用成员变量的类中的拷贝构造函数
class Base
{
public:
Base()
{}
~Base()
{}
Base(Base& obj)
{
cout << "This is base copy constructor!" << endl;
}
};
class Derived
{
public:
Derived()
{}
~Derived()
{}
public:
Base obj;
};
Derived obj;
Derived Obj(obj);
测试结果为:
说明了此时编译器为Derived类合成了一个拷贝构造函数,在合成的拷贝构造函数中调用了Base的拷贝构造函数,上面说了成员变量的类无论是显式声明的拷贝构造函数还是编译器合成的拷贝构造函数,都会触发编译器去为该类合成一个拷贝构造函数,请看如下例子:
class Test
{
public:
Test()
{}
~Test()
{}
public:
Derived m;
};
Test obj;
Test Obj(obj);
测试结果为:
此时的Test类中有个Derived类对象,而该类有一个编译器合成的拷贝构造函数,所以编译器也需要为Test合成一个拷贝构造函数来调用Derived的拷贝构造函数。
2.当一个类的基类有一个拷贝构造函数时(无论是编译器合成的还是显式声明的),编译器会给子类合成一个拷贝构造函数。
class Base
{
public:
Base()
{}
~Base()
{}
Base(Base& obj)
{
cout << "This is base copy constructor!" << endl;
}
};
class Derived : public Base
{
public:
Derived()
{}
~Derived()
{}
};
Derived obj;
Derived Obj(obj);
测试结果为:
说明在基类有显式的拷贝构造函数时,编译器会为子类合成一个拷贝构造函数,合成的拷贝构造函数调用父类的拷贝构造函数,当基类中没有显式的拷贝构造函数,但是有编译器合成的构造函数时,子类也会合成一个拷贝构造函数:
class Test : public Derived
{
public:
Test()
{}
~Test()
{}
};
Test obj;
Test Obj(obj);
测试结果为:
说明在父类中有编译器合成的拷贝构造函数时,子类也需要合成一个拷贝构造函数,来调用父类的拷贝构造函数。
除了以上这两种情况以外还有两种情况,编译器也会合成一个默认的拷贝构造函数,由于另外两种情况较为复杂,将在下一篇文章中分析。