簡體   English   中英

復制構造函數和賦值運算符的類似值的實現

[英]Value -like implementation of copy constructor and assignment operator

幾個月前我問了一個關於復制構造函數和賦值運算符的問題,但我並沒有真正解決它,現在我又被同樣的問題困住了。 我必須實現一個包含指針的類的復制構造函數、賦值運算符和析構函數,並且實現必須是類似值的,即不同的對象不能指向同一個變量。 假設我有這個代碼:

class A{};
class B{
A* item;
int c;
public: 
B(const A& a, int c_): item(new A(a)), c(c_){};
B(const B& b) //copy constructor
B& operator=(const B & b); //assignment operator
~B(); //destructor
}

現在,在我的許多示例中,對這些元素進行編碼的正確方法是:

// copy constructor
B::B(const B& b){
    item = new A(*(b.item));
    c=b.c;
}

這是第一個問題,問題是為什么我需要創建一個新的 A 對象,而不是僅僅將 b.item 指向的值分配給 (*this).item。 上次我被告知分配或延遲未初始化的指針可能會導致奇怪的行為。

// assignment operator

B::operator=(const B& b){
    if(this != &b){
        c=b.c;
        delete item;
        item = new A (*(b.item));
}
}

我可能理解復制構造函數需要 new 運算符,但是為什么我要刪除 item 並重新分配另一個 A 對象,而不是僅僅復制 b.item 在 this->item 中指向的值? 每當代碼使用賦值運算符時,A內部的指針都會被初始化,所以不再存在賦值給未初始化指針的問題,那我為什么要遵循這個過程呢?

如果您有一個對象b1 ,並且您像這樣創建了一個副本b2

B b1;
B b2(b1);

那么你必須為b2.item創建一個新的A對象來引用,否則它們將引用同一個項目:因此你需要在B的復制構造函數中使用new A

現在考慮分配下會發生什么:

B b1;
B b2;
b2=b1;

在這種情況下,默認的復制賦值運算符也會做錯事:它將item指針從b1復制到b2 ,所以現在b1b2將指向同A 因此,您需要編寫一個復制賦值運算符。

由於每個B擁有自己的A ,您有兩種選擇:根據示例復制賦值運算符銷毀並重新創建A對象,或者直接分配包裝的對象:

B& B::operator=(B const& other){  // delete and recreate
  if(&other!=this){
    c=other.c;
    delete item;
    item=new A(*other.item);
  }
  return *this;
}

B& B::operator=(B const& other){  // assign the item
  if(&other!=this){
    c=other.c;
    *item=*other.item;
  }
  return *this;
}

哪個最好取決於A的類型及其一般行為。 例如,如果A不能被分配,那么你必須刪除並重新創建,而如果它可以被分配,那么你可能希望這樣做。

暫無
暫無

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

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