C++/CLI思辨錄之拷貝建構函式
雖然物件複製看上去很簡單,然而如果你沒有對其正確理解,可能會出現一些嚴重問題。預設情況下,複製物件會導致相應的所有成員的複製。如果你只有例項成員,這看上去是相當不錯的。但是如果你的類中含有指向在堆中分配的物件時,情況會怎樣呢?考慮下面的程式碼片斷:
#include <stdio.h>
#include <string.h>
class Person
{
private:
char* _name;
public:
Person()
{
_name = new char[256];
}
void SetName(const char* name)
{
if(strlen(name) + 1 < 256)
strcpy(_name,name);
}
void PrintName()
{
printf("%s/n",_name);
}
};
int main()
{
// 建立物件的第一個例項並賦於名字為John
Person p1;
p1.SetName("John");
p1.PrintName();
//通過複製p1引用的物件建立另一個物件
Person p2(p1);
p2.SetName("Alice");
p2.PrintName();
//現在再輸出p1的名字
p1.PrintName();
scanf("q");
return 0;
}
這裡的類Person有一個指向在堆上分配的字元陣列的指標。當構造Person物件時,它建立該字元陣列並把它的位置存放到變數_name中。
但是當你建立Person 物件 p2 時,p2的成員用p1的成員初始化。因而,p1的 _name與p2的 _name指向相同的堆物件。如在上例中看到的,呼叫p2.SetName將改變由這兩個類共享的值。所以,當第二次呼叫p1.PrintName,列印結果是"Alice"。
所以,這不是我們複製物件所期望的結果,而且還會導致堆崩潰的問題。請再考慮某個函式刪除了該陣列而p1又要呼叫該函式的情況?下面,當p2呼叫PrintName時,它將盡量存取實際上不是在堆上的物件。這種情況下產生的結果往往是難以預料的。
C++允許我們通過定義拷貝建構函式來克服這類問題。在我們每次通過複製另一個物件來初始化一個物件時,拷貝建構函式都被執行。你可以在拷貝建構函式中覆蓋掉預設的成員函式的複製行為。
所以,我們的類Person應該修改如下:
class Person
{
private:
char* _name;
public:
Person()
{
_name = new char[256];
}
// 這是拷貝建構函式。在此我們初始化一個新的陣列,為Person的例項所用
Person(Person&)
{
_name = new char[256];
}
void SetName(const char* name)
{
if(strlen(name) + 1 < 256)
strcpy(_name,name);
}
void PrintName()
{
printf("%s/n",_name);
}
};
這裡類Person中的拷貝建構函式保證了它初始化一個新的陣列,為在複製時產生的每一個物件例項所用。這就避免了前面我們提到的問題。
相關文章
- C++拷貝建構函式(深拷貝,淺拷貝)C++函式
- C++拷貝建構函式詳解C++函式
- C++之Big Three:拷貝構造、拷貝賦值、解構函式探究C++賦值函式
- C++中建構函式,拷貝建構函式和賦值函式的詳解C++函式賦值
- c/c++ 拷貝控制 建構函式的問題C++函式
- 建構函式,拷貝賦值函式的N種呼叫情況函式賦值
- C++ 建構函式和解構函式C++函式
- 類的陣列初始化後會呼叫拷貝建構函式陣列函式
- C++淺拷貝和深拷貝C++
- C++知識點49——類繼承與類的構造、拷貝、operator=和解構函式C++繼承函式
- C++派生類的拷貝構造C++
- C++入門記-建構函式和解構函式C++函式
- 【C++】初始化列表建構函式VS普通建構函式C++函式
- C++複製建構函式C++函式
- jquery之物件拷貝深拷貝淺拷貝案例講解jQuery物件
- JavaScript之深拷貝和淺拷貝JavaScript
- React之淺拷貝與深拷貝React
- js之淺拷貝和深拷貝JS
- C++:String物件的構造及深拷貝C++物件
- 深入分析C++物件模型之移動建構函式C++物件模型函式
- C++型別轉換建構函式C++型別函式
- c++ 的學習 建構函式1C++函式
- 預設建構函式、引數化建構函式、複製建構函式、解構函式函式
- C++建構函式和解構函式呼叫虛擬函式時使用靜態聯編C++函式
- 建構函式之間的呼叫函式
- 迴圈單連結串列建構函式、解構函式C++實現函式C++
- C++——建構函式之初始化列表C++函式
- C++:建構函式的分類和呼叫C++函式
- python深拷貝和淺拷貝之簡單分析Python
- 深度解讀《深度探索C++物件模型》之預設建構函式C++物件模型函式
- 深度解讀《深度探索C++物件模型》之複製建構函式C++物件模型函式
- 建構函式與解構函式函式
- ## 建構函式函式
- Python 擴充之詳解深拷貝和淺拷貝Python
- IOS學習之淺析深拷貝與淺拷貝iOS
- Python3之淺談----深拷貝與淺拷貝Python
- C++ 移動構造和複製建構函式匹配C++函式
- C++學習筆記-----類和建構函式C++筆記函式
- 淺拷貝&深拷貝