2012-04-02 90 views
2

我跑在開發Studio 2010中下面的代碼:奇怪的C++涉及多個調用行爲,析構函數

struct Foo 
{ 
    Foo() {cout << "Foo()" << endl;} 
    ~Foo() {cout << "~Foo()" << endl;} 
    void operator()(const int &) const {} 
}; 

int bar[] = {0}; 
for_each(begin(bar), end(bar), Foo()); 

輸出是不是我所期待的,是在這兩個調試相同,不管釋放「扎」數組的內容:

Foo() 
~Foo() 
~Foo() 
~Foo() 

我已經看過了輸出組件,我不能爲我的生活理解,爲什麼編譯器生成的析構函數額外要求。任何人都可以向我解釋究竟發生了什麼?

+6

加上' Foo(const Foo&){cout <<「Foo(const Foo&)」<< endl;}'並嘗試它。 – 2012-04-02 03:52:12

+1

如果您在構造函數中放置打印件,最好也爲所有編譯器生成的方法執行打印。查看對3/5規則的引用以獲取編譯器生成的方法。 – 2012-04-02 05:14:19

回答

4

這是因爲在程序過程中正在創建和銷燬無名的臨時對象。
通常,在使用標準庫容器和算法時,標準不提供任何保證w.r.t創建臨時對象。如果實現允許創建臨時對象(爲了獲得良好的性能或其他),則允許實現。

請注意,您應該遵循Rule of Three在C++ 03和C++ 11 規則五,以避免由於臨時對象創建的任何問題。

+0

Doh!當然是複製構造函數。謝謝Als。 – 2012-04-02 03:54:21

+0

@MarkFeldman:沒問題。請注意我關於*三/五*規則的評論,這是相當重要的。 – 2012-04-02 04:08:33

1

對於每個模板函數,在使用它的情況下,參數Foo將被鍵入爲Foo,而不是Foo & Foo *。

這意味着Foo對象將被複制。

爲什麼它被複制兩次?一旦進入功能,一旦出來。 for_each會在Foo爭議中複製匿名Foo,然後它將返回它的副本,因爲它的返回類型也是Foo。

爲了詳細說明Als在說些什麼:正在使用複製構造函數。

有它不可複製,你可以明確地輸入作爲參考(不過,作爲阿爾斯說,這將是實現特定的理論,如果它想要的for_each可以作出明確的副本):

for_each<Foo&>(..., ..., ...) 
+0

感謝您進入更多細節Corbin,我將輸出添加到拷貝構造函數中,並準確地看到了我的預期。我認爲我感到困惑,因爲構造函數和析構函數中存在的代碼導致明確調用,而默認的副本構造函數被內聯(即理論上存在,我沒有意識到)。 – 2012-04-02 03:56:31