簡體   English   中英

對象創建中涉及的構造函數和析構函數調用

[英]constructor and destructor calls involved in object creation

我正在使用以下代碼片段來比較在C ++中創建對象的兩種方法。

#include <iostream>

using std::cout;
using std::endl;

class Foo {
    public:
        Foo() : x(0) { cout << "In Foo constructor." << endl; }
        ~Foo() { cout << "In Foo destructor." << endl; }
        Foo(const Foo&) { cout << "In Foo copy constructor." << endl; }

        // Assignment operator.
        Foo& operator=(const Foo&) {
            cout << "In assignment operator." << endl;
            return *this;
        }

    private:
        int x;
};

int main() {

    cout << "Constructing Foo 1" << endl;
    Foo Foo_1;
    cout << "Constructing Foo 2" << endl;
    Foo Foo_2 = Foo();

    return 0;
}

該代碼段的輸出為:

  Constructing Foo 1
  In Foo constructor.
  Constructing Foo 2
  In Foo constructor.
  In Foo destructor.
  In Foo destructor.

我正在使用Visual C ++ 2010 (編譯器版本16.x),並且正在使用cl /EHsc /W4 test.cpp編譯代碼段。 在構建Foo_2 ,我希望看到對構造函數和析構函數的額外調用,以創建一個臨時對象,以及對賦值運算符的調用,以將臨時對象分配給Foo_2 有人可以向我解釋為什么不是這種情況。 抱歉,如果我在這里遺漏了一些非常明顯的內容。

Foo有兩種初始化形式:

Foo f1;
Foo f2 = Foo();

第一個使用默認構造f直接構造f 第二種使用默認構造函數構造Foo類型的臨時對象,並將該臨時對象復制到f2 后者就是您所描述的期望。 而且您是對的,除了一條附加規則:如果該初始化形式有效(就在這里;將副本構造函數設為私有,然后看看會發生什么),則允許編譯器“刪除”副本構造並構造f2直接,就像在第一個版本中一樣。 那就是你所看到的。 不需要編譯器退出副本構造函數,但是我最近使用的每一個都需要這樣做。

Foo Foo_2 = Foo(); 類似於Foo Foo_2(Foo()); 編譯器足夠聰明,可以執行此操作,不會調用賦值運算符。 順便說一句,您在賦值運算符中有一個錯誤-您返回對對象的引用而不是復制它。

第一個“本周專家”問題與您的問題有關, http://www.gotw.ca/gotw/001.htm特別是有關編譯器優化的說明。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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