[英]Why assignment operator = doesn't return the value of pointer but the dereference value?
[英]Why doesn't this assignment operator return a copied object?
我有一個名為 Stack 的 class。 我已經實現了復制構造函數,但是對於復制賦值構造函數,我只是讓它調用復制構造函數,因為邏輯是相同的。 但由於某種原因,它只返回一個默認構造的 object。 我不明白為什么。
復制構造函數:
Stack::Stack( const Stack& s )
{
if ( s.Empty() )
{
this->entry = nullptr;
}
else
{
this->entry = new Entry();
Entry* i = this->entry;
for ( Entry* p = s.entry; p != nullptr; p = p->next )
{
i->number = p->number;
i->next = p->next == nullptr ? nullptr : new Entry();
i = i->next;
}
}
}
復制賦值構造函數:
Stack& Stack::operator=( const Stack& s )
{
return Stack( s );
}
調用代碼:
Stack s;
s.Push( 5 );
s.Push( 3 );
Stack s2;
s2 = s; //s2 just ends up defaulted constructed instead of copied from s
如果我替換這些行:
Stack s2;
s2 = s;
和:
Stack s2(s);
一切正常。 我在這里做錯了什么?
編輯 -
所以這里的教訓是實現分配 ctor 並在復制 ctor 中利用它,而不是像我所做的那樣反過來。
賦值運算符的行為未定義。
您正在返回一個懸空引用。
編寫賦值運算符的慣用方式是std::move
傳遞s
object 的實例(在你的情況下,你應該按值傳遞)給 self,並返回*this
作為參考。
您的賦值運算符不正確。 它返回對臨時 object 的引用。 它應該返回*this
代替:
Stack& Stack::operator=( const Stack& s )
{
// copy s to members
return *this;
}
如果您想避免兩次實現事物,通常更容易實現賦值運算符並在復制構造函數中使用它:
Stack::Stack( const Stack& s )
:Stack()
{
*this = s;
}
Stack& Stack::operator=( const Stack& s )
{
if (&s == this) return *this;
// TODO: free current members?
if ( s.Empty() )
{
this->entry = nullptr;
}
else
{
this->entry = new Entry();
Entry* i = this->entry;
for ( Entry* p = s.entry; p != nullptr; p = p->next )
{
i->number = p->number;
i->next = p->next == nullptr ? nullptr : new Entry();
i = i->next;
}
}
return *this;
}
當你這樣做
Stack& Stack::operator=( const Stack& s )
{
return Stack( s );
}
Stack(s)
創建 object,其中 scope 限制為當前 function。 然后返回對這個本地 object 的引用。
因此,在執行x = y
時,不會將x
修改為y
的副本,並且返回對 scope 之外的 object 的引用,然后將其丟棄。
Stack& Stack::operator=( const Stack& s )
的工作不是返回副本。 它的工作是修改x
(稱為this
)使其等於y
(稱為s
)。
所以,正確的方法看起來像:
Stack& Stack::operator=( const Stack& s )
{
this->entry = new Entry();
// then all the code to make `this` equal to `s`
}
由於您有Stack
的工作副本構造函數和工作析構函數,因此您可以簡單地使用復制/交換來實現賦值運算符:
Stack& Stack::operator=( const Stack& s )
{
if ( this != &s)
{
Stack temp(s);
std::swap(temp.entry, entry);
}
return *this;
}
如果你有其他成員變量,你也需要交換它們。
這是通過創建一個臨時的,並簡單地將當前 object ( this
) 的成員替換為副本的成員來實現的。 然后副本與舊數據一起消失。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.