[英]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
,所以現在b1
和b2
將指向同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.