2016-07-03 78 views
4
#include<iostream> 
#include<vector> 
#include<list> 
#include<queue> 
#include<map> 
using namespace std; 
class dog{ 
    public: 
     string name; 
     dog(); 
     dog(const dog & d); 
     void barkname(){ 
      cout<<"bark "<<name<<endl; 
     } 
     virtual ~dog(){ 
      //cout<<"delete dog "<<name<<endl; 
     } 
}; 

dog::dog(){ 
    cout<<"blank dog"<<endl; 
    this->name="blank"; 
} 

dog::dog(const dog &d){ 
    cout<<"copy dog"<< " "+d.name<<endl; 
    string temp=d.name; 
    this->name=temp+" copied"; 
} 


int main(){ 
    dog d; 
    d.name="d"; 
    dog dd; 
    dd.name="dd"; 
    dog ddd; 
    ddd.name="ddd"; 
    vector<dog> doglist; 
    doglist.push_back(d); 
    doglist.push_back(dd); 
    doglist.push_back(ddd); 
    return 0; 
} 

你好,我是新來的cpp。我試圖在我的班級狗中使用複製構造函數。我使用push_back三次將三隻狗推入矢量中。所以我期望複製構造函數被調用三次。但是,在執行代碼後,我發現,拷貝構造函數被調用六次,結果如下:什麼時候在cpp中調用拷貝構造函數?

blank dog 
blank dog 
blank dog 
copy dog d 
copy dog dd 
copy dog d copied 
copy dog ddd 
copy dog d copied copied 
copy dog dd copied 

我很困惑,爲什麼狗被複制了很多次。我只執行了三次push_back。 謝謝。

感謝您指出了一個類似的問題: why the copy-constructor is called twice when doing a vector.push_back

在這篇文章中,筆者只有一個的push_back對象,但拷貝構造函數得到調用兩次。但是,就我而言,當我調用push_back一次時,複製構造函數只被調用一次。我瞭解我的問題在哪裏,謝謝大家的幫助。

+0

[爲什麼複製構造函數在執行vector.push \ _back時被調用兩次]可能的副本(http://stackoverflow.com/questions/30358475/why-the-copy-constructor-is-called-twice - 當做矢量推回) – Cristy

+0

@Cristy:不是,不。 –

+0

@LightnessRacesinOrbit問題如何不同? :D – Cristy

回答

17

該矢量需要一些地方放狗,所以它爲他們分配內存。但它不能分配無限的內存。隨着你添加更多的狗,矢量需要分配一大塊內存,並且每次它都必須將你的狗放置到他們的新家。要做到這一點,唯一的方法就是將它們複製,然後將原件放入睡眠狀態。

如果你首先爲所有的狗保留了足夠的空間(如下圖所示),那麼這將不是必需的,你的狗可能會開始處理這種行爲是一個正確的滋擾,而沒有不斷移動房屋的分心。

doglist.reserve(3); 
+4

Lol:「它必須將你的狗搬遷到他們的新家」:) – Cristy

+1

它每次重新分配?我聽說矢量預先分配了幾個條目。如果它們存在,他們也不能使用移動構造函數嗎? (他們不在這種情況下,我只是問) –

+3

@PaulStelian:不是每一次 - [增長率不同,但通常是幾何](http://stackoverflow.com/q/5404489/560648)。可能的話,元素將被移動。 –

1

如果添加顯示向量容量的語句,輸出將會更加清晰。例如

#include <iostream> 
#include <string> 
#include <vector> 

using namespace std; 

class dog{ 
    public: 
     string name; 
     dog(); 
     dog(const dog & d); 
     void barkname(){ 
      cout<<"bark "<<name<<endl; 
     } 
     virtual ~dog(){ 
      //cout<<"delete dog "<<name<<endl; 
     } 
}; 

dog::dog(){ 
    cout<<"blank dog"<<endl; 
    this->name="blank"; 
} 

dog::dog(const dog &d){ 
    cout<<"copy dog"<< " "+d.name<<endl; 
    string temp=d.name; 
    this->name=temp+" copied"; 
} 


int main() 
{ 
    dog d; 
    d.name="d"; 
    dog dd; 
    dd.name="dd"; 
    dog ddd; 
    ddd.name="ddd"; 
    vector<dog> doglist; 

    cout << "\nInitial capacity: " << doglist.capacity() << endl; 

    doglist.push_back(d); 

    cout << "After adding the first dog capacity: " << doglist.capacity() << endl; 

    doglist.push_back(dd); 

    cout << "After adding the second dog capacity: " << doglist.capacity() << endl; 

    doglist.push_back(ddd); 

    cout << "After adding the second dog capacity: " << doglist.capacity() << endl; 

    return 0; 
} 

程序輸出是

blank dog 
blank dog 
blank dog 

Initial capacity: 0 
copy dog d 
After adding the first dog capacity: 1 
copy dog dd 
copy dog d copied 
After adding the second dog capacity: 2 
copy dog ddd 
copy dog d copied copied 
copy dog dd copied 
After adding the second dog capacity: 4 

輸出可以根據向量的實現不同。

考慮到輸出,您可以看到最初矢量不會爲可能添加的元素分配內存。其容量等於0.

當添加第一個項目時,向量爲該項目分配內存並將提供的對象複製到該內存中。

當添加第二項時,向量分配一個新的內存範圍,並將新元素和第一個元素從當前內存範圍複製到新內存範圍,依此類推。

你可以說它最初會爲三個項目預留內存的向量。

例如

#include <iostream> 
#include <string> 
#include <vector> 

using namespace std; 

class dog{ 
    public: 
     string name; 
     dog(); 
     dog(const dog & d); 
     void barkname(){ 
      cout<<"bark "<<name<<endl; 
     } 
     virtual ~dog(){ 
      //cout<<"delete dog "<<name<<endl; 
     } 
}; 

dog::dog(){ 
    cout<<"blank dog"<<endl; 
    this->name="blank"; 
} 

dog::dog(const dog &d){ 
    cout<<"copy dog"<< " "+d.name<<endl; 
    string temp=d.name; 
    this->name=temp+" copied"; 
} 


int main() 
{ 
    dog d; 
    d.name="d"; 
    dog dd; 
    dd.name="dd"; 
    dog ddd; 
    ddd.name="ddd"; 
    vector<dog> doglist; 
    doglist.reserve(3); 
    //^^^^^^^^^^^^^^^^^^^ 

    cout << "\nInitial capacity: " << doglist.capacity() << endl; 

    doglist.push_back(d); 

    cout << "After adding the first dog capacity: " << doglist.capacity() << endl; 

    doglist.push_back(dd); 

    cout << "After adding the second dog capacity: " << doglist.capacity() << endl; 

    doglist.push_back(ddd); 

    cout << "After adding the second dog capacity: " << doglist.capacity() << endl; 

    return 0; 
} 

在這種情況下,輸出將看起來像

blank dog 
blank dog 
blank dog 

Initial capacity: 3 
copy dog d 
After adding the first dog capacity: 3 
copy dog dd 
After adding the second dog capacity: 3 
copy dog ddd 
After adding the second dog capacity: 3 

因此,在這種情況下,只有載體拷貝在預分配的存儲器範圍的新添加的項。

相關問題