2016-04-08 5 views
0

push_back,emplaceおよびinsertのコピーコンストラクタの異常な動作。push_back vs empleとC++のベクターへの挿入

#include<iostream> 
#include<memory> 
#include<vector> 
using namespace std; 
class Test 
{ 
    private: 
    int *big; 
    public: 
    void make_null() 
    { 
     delete [] big; 
     big = NULL; 
     cout<<"Made NULL\n"; 
    } 
    void show() { cout<<"Memory Allocated\n"; } 
    Test() 
    { 
     big = new int[10000]; 
     cout<<"Default Constructor gets called \n"; 
    } 
    Test(const Test &a) 
    { 
     big = new int[10000]; 
     int k; 
     for(k = 0; k < 10000 ; k++) 
     big[k] = a.big[k]; 
     cout<<"Copy Constructor gets called \n"; 
    } 
    Test & operator = (const Test &a) 
    { 
     if(this != &a) 
     { 
     delete [] big; 
     if(a.big) 
     { 
      big = new int[10000]; 
      int k; 
      for(k = 0; k < 10000 ; k++) 
       big[k] = a.big[k]; 
      cout<<"New memory gets allocated \n"; 
     } 
     else 
     { 
      big = NULL; 
      cout<<"NULL value gets assigned \n"; 
     } 
     } 
     else 
     cout<<"Same pointer assignment\n";  
     cout<<"Assignment operator gets called \n"; 
     return *this; 
    } 
    ~Test() 
    { 
     delete [] big; 
     cout<<"Destructor gets called \n"; 
    } 
}; 
int main() 
{ 
    Test tObj; 
    vector<Test> tVec; 
    tVec.push_back(tObj); 
    tVec[0].show(); 
    cout<<"++++++++++++++++++++++++++++++++++++++++++++++++++\n"; 
    Test rObj; 
    tVec.emplace(tVec.end(),rObj); 
    tVec[1].show(); 
    cout<<"++++++++++++++++++++++++++++++++++++++++++++++++++\n"; 
    Test qObj; 
    tVec.insert(tVec.end(),qObj); 
    tVec[2].show(); 
    cout<<"++++++++++++++++++++++++++++++++++++++++++++++++++\n"; 
    Test sObj; 
    vector<Test> sVec; 
    sVec.push_back(sObj); 
    sVec[0].show(); 
    cout<<"++++++++++++++++++++++++++++++++++++++++++++++++++\n"; 
    tVec[0] = tVec[0]; 
    tVec[0] = sVec[0]; 
    sVec[0].make_null(); 
    tVec[1] = sVec[0]; 
    return 0; 
} 

OUTPUT:

Default Constructor gets called 
Copy Constructor gets called 
Memory Allocated 
++++++++++++++++++++++++++++++++++++++++++++++++++ 
Default Constructor gets called 
Copy Constructor gets called 
Copy Constructor gets called 
Destructor gets called 
Memory Allocated 
++++++++++++++++++++++++++++++++++++++++++++++++++ 
Default Constructor gets called 
Copy Constructor gets called 
Copy Constructor gets called 
Copy Constructor gets called 
Destructor gets called 
Destructor gets called 
Memory Allocated 
++++++++++++++++++++++++++++++++++++++++++++++++++ 
Default Constructor gets called 
Copy Constructor gets called 
Memory Allocated 
++++++++++++++++++++++++++++++++++++++++++++++++++ 
Same pointer assignment 
Assignment operator gets called 
New memory gets allocated 
Assignment operator gets called 
Made NULL 
NULL value gets assigned 
Assignment operator gets called 
Destructor gets called 
Destructor gets called 
Destructor gets called 
Destructor gets called 
Destructor gets called 
Destructor gets called 
Destructor gets called 
Destructor gets called 

emplaceは 、それを2回呼び出し、insertは三度それを呼び出している間push_back呼び出しは、一度コンストラクタをコピーします。 私はその背後にある理由が何であるか把握できません。主な機能にはこの行の後に

+0

前の要素の再割り当て。 – LogicStuff

+0

コピーコンストラクタの呼び出し頻度を確認するには、このコードの壁が本当に必要ですか?最小限に抑えてください。あなたは質問をするのを忘れてしまった;) – user463035818

+0

質問は、コピーコンストラクタが挿入と置き換えの場合に2回以上呼び出された理由と、コピーコンストラクタをプッシュバックするのではなく、 (tobi303)大変申し訳ありません。不必要な部分を無理に除外します。 (LogicStuff)申し訳ありませんが、私はあなたの答えを得ることができません詳細で詳細を教えてください。 – user3798283

答えて

0

vector<Test> tVec; 

ちょうどこの追加:あなたの問題は消えます

tVec.reserve(N); // N is the number of items you think that you are going to add to the vector 

を。

なぜですか?

std::vector(push、emplaceまたはinsert)に要素を追加すると、再割り当てが行われる可能性があります。再配置によって、すべてのアイテムがメモリの新しい場所(ヒープ)にコピーされます。要素をコピーすると、コピーコンストラクタを忌避して呼び出し、古い項目のデストラクタを呼び出します。

tVec.reserve(N);は、連続したメモリブロックを予約します。これにより、押された要素の数がN未満になるまで、再割り当てが防止されます(または、言い換えれば、それは必要ありません)。

+0

**簡単なテストプログラムのために** 99999要素を予約するだけではありません。いくつかの数字を追加すると、新しい問題が表示されます。妥当な金額を予約しても構いませんが、99999要素を予約すると、こんにちは世界のプログラムは多すぎますか? – aslg

+0

必ずご確認ください。これは現実世界のコードではありません。とにかく私は編集するつもりです。ありがとう –

関連する問題