[英]Why doesn't default assignment operator call the destructor first?
因此,在下面的示例中,我們使類Foo
用*this = Foo()
替換自身。 我很高興我只是測試了這個,因為事實證明,在這種情況下,舊Foo
的析構函數不會被調用。 我想這是因為默認賦值運算符只使用memcpy
...但是作為一個語言設計問題...為什么不讓默認賦值運算符首先破壞已分配的對象以防止意外?
#include <iostream>
using namespace std;
class MustBeDestroyed //(for some reason not shown here)
{
public:
int i;
MustBeDestroyed(int i) : i(i) {}
~MustBeDestroyed() { cout << "destroyed contained class " << i << endl; }
};
class Foo
{
public:
MustBeDestroyed x;
Foo(int y) : x(y) {}
void replace_myself(int y) { Foo f(y); *this=f; }
void print() { cout << "This is outer/inner class " << x.i << endl; }
~Foo() { cout << "destroyed outer class " << x.i << endl; }
};
int main()
{
Foo a(1);
a.print();
a.replace_myself(2);
a.print();
return 0;
}
因為首先破壞對象會終止生命。 然后,您必須調用構造函數來啟動新對象的生命周期。 但是operator =的行為不是要銷毀當前對象並創建另一個對象,而是要為現有對象分配一個新值。
基本上,你違反了3的規則。
為什么賦值會調用析構函數? 它完全按照它的說法執行:它調用賦值運算符。 編譯器生成的賦值運算符只是顯而易見:將舊obejct中的所有成員分配給new(使用它們的賦值操作)。 沒有更多,沒有更少。 這正是着名的三人統治的原因。
現在它為什么不調用析構函數:這將結束對象的生命周期。 雖然理論上可能構造一個新對象而不是舊對象,但是在異常面前這種方法通常是不正確的( 關於這個問題,請查看這個問題 ),因此它不能用於一般情況。 如果它采用你提出的方法,它不會為成員調用賦值運算符,而是調用析構函數/復制構造函數。 這意味着不會遵守自定義分配行為(實際上不需要與復制行為相同)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.