對於拷貝構造函數,我們並不陌生,就是將相同類型的一個對象拷貝到另一個對象。對於拷貝構造函數如果我們沒有手動實現,在有些場景下當有對象拷貝操作時編譯器會爲類合成一個拷貝構造函數。具體有哪些場景下面一一介紹:
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; 這裏會調用拷貝構造函數來拷貝虛基類表指針。