push_back
,emplace
和insert
的复制构造函数的奇怪行为。
#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;
}
输出:
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
push_back
调用复制构造函数一次,而emplace
调用它两次,
并insert
称之为三次。
我无法弄清楚背后的原因是什么。
答案 0 :(得分: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
添加元素(推送,插入或插入)时,可能会发生重新分配。重新分配将导致将所有项目复制到内存(堆)的新位置。复制元素将默认调用复制构造函数,然后调用析构函数以获取旧项目。
tVec.reserve(N);
将保留连续的内存块。这将阻止重新分配(或更好地说,不需要),直到推送元素的计数小于N
。