使用類建立物件時,建構函式被自動呼叫以完成物件的初始化,那麼能否象簡單變數的初始化一樣,直接用乙個物件來初始化另乙個物件呢?
答案是可以:
student s1;
student s2=s1;
像這種語句在語法上是合法的。
初始化s2,相當於將s1中每個資料成員的值複製到s2中,這是表面現象。實際上,系統呼叫了乙個複製建構函式。如果類定義中沒有顯式定義該複製建構函式時,編譯器會隱式定義乙個預設的複製建構函式,它是乙個inline、public的成員函式,其原型形式為: 類名::類名(const 類名 &)
注意:當我們自己定義了有參建構函式時,系統不再提供預設建構函式。這是容易忽略的一點。
看乙個例子:
#includeusing namespace std;
class student
student(const student& s)
private:
char name[20];
int num;
};int main()
首先我們定義乙個類,其次在main函式中初始化乙個物件s1;用s1初始化s2。按理來說,執行的結果應該是預設構造引數,但是實際:
他不僅呼叫了預設建構函式,而且呼叫了拷貝建構函式。
事實上:一共有三種情況會呼叫拷貝建構函式
1.乙個物件作為函式引數,以值傳遞的方式傳入函式體
2.乙個物件作為函式返回值,以值從函式返回
3.乙個物件用於給另外乙個物件進行初始化(賦值初始化)
以上三種情況會預設呼叫拷貝建構函式。如果我們不自己在類內寫拷貝建構函式,那麼出現以上情況會自動呼叫預設的拷貝建構函式。
可能有小夥伴就會問了,呼叫就呼叫吧,關我啥事?
但實際上他可能就會出現問題:
在看乙個例子:
#includeclass demo
~demo()
private:
int* p;
};int main()
用物件a初始化b時,會呼叫預設拷貝建構函式。
這裡涉及深拷貝和淺拷貝的問題:
深拷貝和淺拷貝可以簡單理解為:如果乙個類擁有資源,當這個類的物件發生複製過程的時候,資源重新分配,這個過程就是深拷貝,反之,沒有重新分配資源,就是淺拷貝。
我們定義的類中存在指標,但在呼叫a初始化b的過程中只是簡單的拷貝了指標中記憶體的位址。兩個物件的析構函式將對同乙個記憶體空間釋放兩次。在執行時就會報段錯誤
那麼如何避免這種情況呢?
三大定律(rule of three / the law of the big three / the big three)
如果類中明確定義下列其中乙個成員函式,那麼必須連同其他二個成員函式編寫至類內,即下列三個成員函式缺一不可:
1.析構函式(destructor)
2.複製建構函式(copy constructor)
3.複製賦值運算子(copy assignment operator)
c 複製 拷貝建構函式
在c 中,定義乙個空類時,編譯器會預設宣告6個成員函式,它們分別是 class empty 注意 一下,編譯器預設合成的析構函式不是虛函式。首先,說一下什麼是拷貝建構函式 也可以叫複製建構函式 它是乙個特殊的建構函式,具有單個形參 此形參是對該類型別的引用,需要用const修飾,否則會無限迴圈呼叫複...
c 拷貝(複製)建構函式
class line line line const line obj 拷貝建構函式是一種特殊的建構函式,它在建立物件時,是使用同一類中之前建立的物件來初始化新建立的物件。拷貝建構函式通常用於 1 通過使用另乙個同型別的物件來初始化新建立的物件,即用已有物件給新建立物件賦值。line line1 1...
拷貝建構函式(複製建構函式)
執行 物件a 物件b時,系統需要呼叫拷貝建構函式,如果程式設計師沒寫,則呼叫預設的拷貝建構函式。預設的拷貝建構函式利用淺拷貝方式,它的樣子是 a const a a 淺拷貝 拷貝的時候,兩個指標指向同乙個區域 char str1 helloworld char str2 str1 深拷貝 拷貝的時候...