歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> C++ 復制構造函數詳解

C++ 復制構造函數詳解

日期:2017/3/1 9:17:45   编辑:Linux編程

C++類的設計中,如果某些函數沒有顯式定義,C++會自動生成,復制構造函數便是其中之一,其他的還有默認構造函數、賦值操作符、默認析構函數、地址操作符。一個類的復制構造函數的原型一般為: Class_name (const Class_name &);

一、何時調用復制構造函數

  在新建一個對象並將其初始化為同類對象的時候,常常會調用復制構造函數,如:

    Class_name A(B);

    Class_name A = B ;

    Class_name A = Class_name(B);

    Class_name *p = new Class_name(A);// 用A初始化一個匿名對象,並將其地址賦予指針P

  每當程序生成對象副本時,編譯器都會調用復制構造函數。具體地說,當函數按值傳遞對象或生成臨時對象時,編譯器都會調用復制構造函數。如當3個Vector對象相加時,編譯器會調用復制構造函數來生成臨時對象。

二、復制構造函數的淺復制

  默認的復制構造函數是淺復制,即逐個復制非靜態成員數據的值。

  (1)如果類成員是另一個類的對象,那麼將調用另一個對象的復制構造函數;

  (2)靜態成員數據不被復制,因為它們屬於整個類,而不是一個對象。

  (3)如果成員中含有含有指針P,那麼它的地址也會賦給新的對象中相應的P,這樣會導致兩個或多個變量指向同一個指針——比較危險的一件事。

三、復制構造函數的深復制

  顯式地定義復制構造函數可以有效解決淺復制的弊端。下面以一個自定義的MyString類作為例子:

  假若是使用默認的復制構造函數,則程序很容易崩潰,比如當你創建了對象A,用A初始化B(A和B的str指向同一個地址),然後銷毀A(此時A的str指向的內存已被收回),之後你如果想銷毀B,則可能使程序崩潰。

  解決方法是顯式定義復制構造函數:

  在函數中使用動態內存分配,在函數裡面也可以顯性改變靜態數據成員的值。與new相對應,在析構函數中使用delete關鍵字銷毀內存:

  End.

Copyright © Linux教程網 All Rights Reserved