3 回答

TA貢獻1839條經(jīng)驗 獲得超15個贊
復制構(gòu)造函數(shù)對曾經(jīng)是原始內(nèi)存的對象執(zhí)行首次初始化。賦值運算符OTOH用新值覆蓋現(xiàn)有值。通常涉及解散舊資源(例如,內(nèi)存)并分配新資源。
如果兩者之間有相似之處,那就是賦值運算符執(zhí)行銷毀和復制構(gòu)造。一些開發(fā)人員過去實際上是通過就地銷毀,然后是布局復制構(gòu)造來實現(xiàn)分配的。但是,這是一個非常糟糕的主意。(如果這是派生類分配期間調(diào)用的基類的賦值運算符,該怎么辦?)
swap正如Charles所建議的,如今通常被認為是規(guī)范用語的是:
MyClass& operator=(MyClass other)
{
swap(other);
return *this;
}
這使用了復制構(gòu)造(注意other已復制)和銷毀(它在函數(shù)末尾被銷毀)-并且它也以正確的順序使用它們:銷毀(必須失?。┲暗臉?gòu)造(可能失敗)。

TA貢獻1812條經(jīng)驗 獲得超5個贊
有些事情困擾著我:
MyClass& operator=(const MyClass& other)
{
MyClass tmp(other);
swap(tmp);
return *this;
}
首先,當我的思想是“復制”時,讀“交換”一詞會激怒我的常識。另外,我對這個幻想的目的提出了質(zhì)疑。是的,在構(gòu)造新的(復制的)資源時,任何異常都應(yīng)該發(fā)生在交換之前,這似乎是一種確保所有新數(shù)據(jù)都被填充后才能上線的安全方法。
沒關(guān)系。那么,交換之后發(fā)生的異常又如何呢?(當臨時對象超出范圍時,舊資源被破壞時)從分配用戶的角度來看,該操作失敗了,但沒有失敗。它具有巨大的副作用:復制確實發(fā)生了。只是某些資源清除失敗。即使從外部看來操作失敗,目標對象的狀態(tài)也已更改。
因此,我建議不要“交換”來進行更自然的“轉(zhuǎn)移”:
MyClass& operator=(const MyClass& other)
{
MyClass tmp(other);
transfer(tmp);
return *this;
}
仍然存在臨時對象的構(gòu)造,但是下一個直接的操作是在將源的資源移動到目的地之前,釋放目標的所有當前資源(并且為NULL,這樣它們就不會被雙重釋放)。
我提出了{構(gòu)造,破壞,移動}而不是{構(gòu)造,移動,破壞}。此舉是最危險的舉動,是在解決所有其他問題后采取的最后一步。
是的,無論哪種方案,銷毀失敗都是一個問題。數(shù)據(jù)已損壞(在您不認為是復制時復制)或丟失(在您不認為是被釋放時釋放)。丟失總比損壞好。沒有數(shù)據(jù)比壞數(shù)據(jù)更好。
轉(zhuǎn)移而不是交換。無論如何,這是我的建議。
- 3 回答
- 0 關(guān)注
- 453 瀏覽
添加回答
舉報