2010-04-17 142 views
2

[跟進到this question]外部調用拷貝構造函數和析構函數

class A 
{ 
    public: 
     A()   {cout<<"A Construction"  <<endl;} 
     A(A const& a){cout<<"A Copy Construction"<<endl;} 
     ~A()   {cout<<"A Destruction"  <<endl;} 
}; 

int main() { 
    { 
     vector<A> t; 
     t.push_back(A()); 
     t.push_back(A()); // once more 
    } 
} 

輸出是:

A Construction  // 1 
A Copy Construction // 1 
A Destruction   // 1 
A Construction  // 2 
A Copy Construction // 2 
A Copy Construction // WHY THIS? 
A Destruction   // 2 
A Destruction   // deleting element from t 
A Destruction   // deleting element from t 
A Destruction   // WHY THIS? 

回答

16

清楚地看到發生了什麼事情,我建議包括this輸出中的指針來標識哪個A正在調用方法。

 A()   {cout<<"A (" << this << ") Construction"  <<endl;} 
    A(A const& a){cout<<"A (" << &a << "->" << this << ") Copy Construction"<<endl;} 
    ~A()   {cout<<"A (" << this << ") Destruction"  <<endl;} 

我已經得到了輸出

A (0xbffff8cf) Construction 
A (0xbffff8cf->0x100160) Copy Construction 
A (0xbffff8cf) Destruction 
A (0xbffff8ce) Construction 
A (0x100160->0x100170) Copy Construction 
A (0xbffff8ce->0x100171) Copy Construction 
A (0x100160) Destruction 
A (0xbffff8ce) Destruction 
A (0x100170) Destruction 
A (0x100171) Destruction 

所以流量可以解釋爲:

  1. 臨時A(... CF)創建。
  2. 將臨時A(... cf)複製到向量(... 60)中。
  3. 臨時A(... cf)被銷燬。
  4. 另一個臨時A(... ce)被創建。
  5. 載體被擴展,且舊A(... 60)在該矢量被複制到新的地方(... 70)
  6. 的其他臨時A(... CE)被複制到載體(... 71 )。
  7. A(... 60,... ce)的所有不必要的拷貝現在都被銷燬了。
  8. 矢量被破壞,所以A的(... 70,... 71)裏面也被破壞。如果你這樣做

    vector<A> t; 
        t.reserve(2); // <-- reserve space for 2 items. 
        t.push_back(A()); 
        t.push_back(A()); 
    

第5步將不復存在輸出將變爲:

A (0xbffff8cf) Construction 
A (0xbffff8cf->0x100160) Copy Construction 
A (0xbffff8cf) Destruction 
A (0xbffff8ce) Construction 
A (0xbffff8ce->0x100161) Copy Construction 
A (0xbffff8ce) Destruction 
A (0x100160) Destruction 
A (0x100161) Destruction 
+0

@KennyTM:極好的方法和解釋!謝謝! – Lazer 2010-04-17 08:39:52