2017-07-04 91 views
3

的順序我有以下C++代碼(VS2013):C++ - 製造和破壞

#include <iostream> 
using namespace std; 
class A { 
    int i; 
public: 
    A(int i) : i(i) { 
     cout << "DEFAULT CTOR " << i << endl; 
    } 
    A(const A &o) : i(o.i) { 
     cout << "COPY CTOR " << i << endl; 
    } 
    ~A() { 
     cout << "DTOR " << i << endl; 
    } 
    friend A f(const A &, A, A *); 
}; 
A f(const A &a, A b, A *c) { 
    return *c; 
} 
int main() { 
    f(1, A(2), &A(3)); 
} 

它產生以下輸出:

DEFAULT CTOR 1

DEFAULT CTOR 3

DEFAULT CTOR 2

COPY CTOR 3

析構函數2

析構函數3

析構函數3

析構函數1

前3是參數構造(wrongfuly outputing 「DEFAULT CTOR」,但沒有按不要緊),在調用f之前調用它。

然後,當return *c;線路運行時,拷貝構造與值3運行,接着該對象的破壞與值2

最後,在main的範圍的端部,將剩餘物體(3,3,1)被破壞。

我不明白這種行爲,沒有找到任何解釋。

任何人都可以詳細說明發生的事情的順序嗎?

具體來說:

  1. 爲什麼在第三對象&A(3)第二對象A(2)以前建造?這與他們的創作有什麼關係(第三個是參照,第二個是價值),還是以f的方式定義(第二個是價值,第三個是指針)?

  2. return *c;運行時,將創建第三個對象的副本以返回。 然後,在返回之前被破壞的唯一對象是第二個對象。同樣,這與他們的創作有什麼關係,或者與f的定義方式有關?

在此先感謝。

+6

你所說的「DEFAULT CTOR」是* not *默認的構造函數。可以使用* no *參數調用默認構造函數。 –

+8

至於你的第一個問題,沒有指定參數的[評估順序](http://en.cppreference.com/w/cpp/language/eval_order)。它可以是編譯器想要的任何東西。 –

+0

有些程序員老兄,是的,你是對的。我現在將編輯我的帖子。 – Gil

回答

6

爲什麼在第二個對象A(2)之前構造第三個對象& A(3)?這與他們的創作有什麼關係(第三個是引用,第二個是價值)還是用f定義的方式(第二個是價值,第三個是指針)?

發生這種情況的原因是函數參數的求值順序未被C++標準指定。編譯器可以評估它們,但它喜歡。這是許多未定義行爲實例的原因,當程序員不知道這一點時依賴於不存在的排序。

當返回* c;運行時,會創建第三個對象的副本以返回。然後,在返回之前被破壞的唯一對象是第二個對象。同樣,這與它們的創造有什麼關係,或者與f的定義方式有關?

的種類,是的。 A(2)對象通過直接初始化函數f的參數來創建。函數參數的範圍是函數的主體。所以A(2)在函數退出的時候超出了範圍。其他對象的生命期稍長,因爲它們是在函數之外創建的,並通過引用/指針傳遞。它們一直存在到完整表達式f(1, A(2), &A(3));的末尾,所以它們在後面被破壞。