#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三次将三只狗推入载体。所以我期望复制构造函数被调用三次。但是,在执行代码之后,我发现复制构造函数被调用了六次,结果如下:
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 :(得分:17)
载体需要一些地方放置你的狗,所以它为它们分配内存。但它不能分配无限的内存。当您添加更多狗时,矢量需要分配更大的内存块,每次执行此操作时,它必须将您的狗重新安置到新家。与你目前设计的课程一样,这样做的唯一方法是复制它们,然后将原件放入睡眠状态。
如果你首先为所有狗保留了足够的空间(如下图所示),那么这不是必要的,你的狗可能已经开始了一个正确的滋扰,没有不断移动房子的分心。
doglist.reserve(3);
答案 1 :(得分: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
因此,在这种情况下,向量仅复制预先分配的内存范围中新添加的项目。