2012-02-28 50 views
0
class B 
{ 

private: 
int _x; 
public: 
int get(){return _x;}; 
B(int x=10):_x(x){cout<<"Default constructor "<<endl;} 
~B(){cout<<"destructor "<<endl;} 
B(const B &rhs){cout<<"copy constructor"<<endl;} 
B& operator =(const B &rhs){cout<<"copy assignment operator"<<endl;} 
int operator *(){cout<<"operator *"<<endl;return _x;} 
}; 

int main() 
{ 
vector<B> v; 
int i; 
vector<B>::iterator ii=v.begin(); 

for(i=0;i<1;i++) 
{ 
v.push_back(*(new B(i*100))); 
} 
ii = v.begin(); 
cout<<"#####################"<<endl; 
ii = v.insert(ii+1,*(new B())); 
cout<<"#####################"<<endl; 

return 0; 
} 

輸出:STL載體插入 - 複製構造

Default constructor 
    copy constructor 
    ##################### 
    Default constructor 
    1. copy constructor 
    2. copy constructor 
    destructor 
    ##################### 
    destructor 
    destructor 

這是爲什麼在v.insert(II,*(新B()));, 2個拷貝構造函數的調用??

+3

C++是**不是** Java。你應該**從不**寫入任何東西:'push_back(*(new B(i * 100)))''。它在堆上創建一個B *實例,然後忘掉它。做事情你基本上是在泄漏記憶。你可以使用'push_back(B(i * 100))'或者''push_back(i * 100)''因爲你的'B'類可以隱式構造。 – ereOn 2012-02-28 15:30:16

回答

5

首先你有內存泄漏,因爲你沒有刪除從new分配的內存。做你想做的事情的正確方法是v.push_back(B(100));

關於爲什麼複製ctor被調用兩次,它看起來像在第二次插入矢量已達到其容量並正在重新分配。在重新分配期間,它將先前插入的元素複製到新分配的內存中。因此你會看到拷貝文件被調用兩次。

1

一個更糟糕的問題是*(new B())是內存泄漏 - 您複製一個動態分配的對象,然後丟棄指向它的唯一指針。您應該創建一個臨時的對象,而不是:

v.insert(ii+1, B()); 

要回答這個問題:因爲向量被存儲爲連續的內存塊,有時需要增加容量,因爲他們成長。發生這種情況時,數組中的所有對象都必須複製(或移動)到其新位置。所以在這裏你看到一個副本移動現有的元素,第二個插入新的元素。