对于拷贝构造函数,我们并不陌生,就是将相同类型的一个对象拷贝到另一个对象。对于拷贝构造函数如果我们没有手动实现,在有些场景下当有对象拷贝操作时编译器会为类合成一个拷贝构造函数。具体有哪些场景下面一一介绍:
class A{
public:
int a;
};
A a_obj;
a_obj.a = 10;
A b_obj = a_obj;
cout<<" b_obj a= "<<b_obj.a<<endl;
此时打印输出为10,看似a_obj被拷贝到了b_obj,但编译器并没有为类A合成拷贝构造函数。对于非类成员数据的拷贝是由编译器其他做法完成,这些简单的数据赋值还用不上拷贝构造函数。
1.含有类成员的类,且类成员含有拷贝构造函数
class A{
public:
int a;
A(const A &a_obj){a = a_obj};
};
class B{
public:
int b;
A m_a;
};
B b_obj;
b_obj.b = 10;
b_obj.m_a.a = 100;
B cb_obj = b_obj;
这一步骤会让编译器合成类B的拷贝构造函数,且这个拷贝构造函数会调用A的拷贝构造函数。
2.父类含有拷贝构造函数
class B:A{
public:
int bb;
}
B b_obj;
b_obj.bb = 10;
b_obj.a = 100;
B cb_obj = b_obj;运行到这一步骤,编译器会产生B的拷贝构造函数,且B的拷贝构造函数会调用父类A的拷贝构造函数。
3.类中含有虚函数
class B{
public:
int bb;
virtual void vfun1(){cout<<"this is a virtual func"<<endl}
}
B b1;
b1.bb = 10;
B b2 = b1;运行到这一步骤,编译器会合成类B的拷贝构造函数,因为需要把b1的虚函数指针拷贝到b2。
4.含有虚基类
class Base{
public:
int m_base_i;
};
class Derived1:virtual Base{
};
class Derived2:virtual Base{
};
class A:public Derived1,public Derived2{
};
A a;
A new_a = a; 这里会调用拷贝构造函数来拷贝虚基类表指针。