簡體   English   中英

為什么默認賦值運算符不首先調用析構函數?

[英]Why doesn't default assignment operator call the destructor first?

因此,在下面的示例中,我們使類Foo*this = Foo()替換自身。 我很高興我只是測試了這個,因為事實證明,在這種情況下,舊Foo的析構函數不會被調用。 我想這是因為默認賦值運算符只使用memcpy ...但是作為一個語言設計問題...為什么不讓默認賦值運算符首先破壞已分配的對象以防止意外?

http://codepad.org/9WCo6yZ5

#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.

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