簡體   English   中英

為什么以及何時應該在C ++中使用Copy Constructor? 為什么不鼓勵淺拷貝呢?

[英]Why and when should use a Copy Constructor in C++? Why shallow copy is discouraged?

讓我們說我們創建一個類Student的對象,我們創建兩個實例/對象類Student(即StudentA和StudentB)。 我們使用淺層復制來初始化B的數據成員,如下所示:

學生B =學生A;

然后我們摧毀了StudentB。 我們在這里面臨懸空指針的情況嗎? 為什么以及如何? 請解釋。

我們在這里面臨懸空指針的情況嗎? 為什么以及如何? 請解釋。

這取決於學生的實施。 如果學生看起來像這樣......

class Student
{
public:
  char* m_name;
  Student(const char* name)
  {
    m_name = new char[strlen(name)+1];
    strcpy(m_name,name);
  }
  ~Student()
  {
    delete[] m_name;
  }
};

...然后出現問題:當你復制一個學生時,你有兩個指向相同m_name數據的指針,當兩個學生實例被刪除時,m_name數據被刪除兩次,這是非法的。 為避免該問題,Student需要一個顯式的復制構造函數,以便復制的Student具有指向不同m_name數據的指針。

或者,如果學生看起來像這樣......

class Student
{
public:
  std::string m_name;
  Student(const char* name)
    : m_name(name)
  {
  }
};

...然后沒有問題,因為魔術(即顯式復制構造函數)是在std :: string類中實現的。

總之,如果類包含分配和刪除的指針,則需要顯式復制構造函數(或者顯式沒有復制構造函數,但在任何一種情況下,不僅僅是默認構造函數)。

真的不鼓勵淺層復制 - 這是一個知道什么時候合適的問題。

這里的問題是“所有權”之一。 “Student”類是否“擁有”指向的數據,因此負責(在其析構函數中)刪除該數據。

基本上,如果您獲取擁有某些指向數據的對象的淺表副本,然后銷毀原始數據或副本,則刪除指向數據(由析構函數刪除)。 但是你仍然在對象中有一個沒有被破壞的引用 - 一個懸垂的指針。

OTOH,如果對象不擁有指向的數據,析構函數不會刪除指向的數據,並且沒有問題。 雖然你必須確保某些東西擁有指向的數據,否則你會有內存泄漏。

跟蹤指向數據的所有權是非垃圾收集語言(如C ++)的關鍵技能,並且是應用資源分配初始化模式的基礎。

簡單來說: 如果您的類成員變量包含它也擁有的指針。

另一點是成員的指向數據是不可變的。 通過使用引用計數智能指針在實例之間共享它是不可觀察的。 例如,我有一些看起來像的代碼

struct SizeContainer {
  // ... stuff ...
private:
  boost::shared_ptr<SizeExpression> p;
};

我沒有聲明復制構造函數和復制賦值運算符,因為無論如何都無法更改p ,因此可以跨多個實例共享它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM