C 基礎3 拷貝 複製 建構函式

2021-09-25 09:58:18 字數 1742 閱讀 7917

使用類建立物件時,建構函式被自動呼叫以完成物件的初始化,那麼能否象簡單變數的初始化一樣,直接用乙個物件來初始化另乙個物件呢?

答案是可以:

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 深拷貝 拷貝的時候...