我有一个Class Child,并且有一个简单的 vector 推回实现,如下所示:
#include <stdio.h>
#include <vector>
#include <iostream>
class Child
{
public:
Child();
Child(const Child &item);
~Child();
};
Child::Child()
{
std::cout<<"Constructing Child\n";
}
Child::Child(const Child &item)
{
std::cout<<"Copy-Constructing Child\n";
}
Child::~Child()
{
std::cout<<"Destructing Child\n";
}
int main()
{
std::vector<Child> v;
Child Item1;
v.push_back(Item1);
}
在
v.push_back( Item1 );
被调用之后,我有以下输出:Constructing Child
Copy-Constructing Child
Copy-Constructing Child
Destructing Child
我期望
Copy-Constructing Child
仅出现一次。为什么复制构造函数被调用两次? 最佳答案
官方答案:对于您的类(class),std::vector可自由制作任意数量的副本,因为标准中没有指定限制。
可能正在发生的事情:在将对象作为参数传递时以及在对 vector 进行内部调整大小时再次进行复制。
这不是效率低下吗?是
我该如何改善?
删除自定义析构函数和复制构造函数,或者定义自定义移动构造函数和复制运算符。前者允许编译器创建自己的移动操作,后者提供它们。
一旦编译器可以推断出您的类是可移动的,std::vector的操作就会变得更加高效,并且您将看到一个完全相同的副本(因为您通过强制编译器通过命名Child
称为Item1
来创建一个副本)
编辑:考虑这个例子
#include <stdio.h>
#include <vector>
#include <iostream>
class Child
{
public:
Child();
Child(const Child &item);
Child(Child&& item);
Child& operator=(const Child &item);
Child& operator=(Child&& item);
~Child();
private:
std::string name() const {
return std::string { _zombie ? "zombie" : "child" };
}
bool _zombie = false;
};
Child::Child()
{
std::cout << "constructing " << name() << "\n";
}
Child::Child(const Child &item)
{
std::cout << "copy-constructing " << name() << "\n";
}
Child::Child(Child &&item)
{
std::cout << "move-constructing " << name() << "\n";
item._zombie = true;
}
Child& Child::operator=(const Child &item)
{
_zombie = false;
std::cout << "assigning " << name() << "\n";
return *this;
}
Child& Child::operator=(Child &&item)
{
item._zombie = true;
_zombie = false;
std::cout << "move-assigning " << name() << "\n";
return *this;
}
Child::~Child()
{
std::cout << "destructing " << name() << "\n";
}
using namespace std;
int main(int argc, const char * argv[])
{
{
std::vector<Child> v;
Child item1;
v.push_back(item1);
}
cout << endl;
{
std::vector<Child> v;
v.push_back(Child{});
}
cout << endl;
{
std::vector<Child> v;
Child item1;
v.push_back(std::move(item1));
}
cout << endl;
return 0;
}
样本输出:
constructing child
copy-constructing child
destructing child
destructing child
constructing child
move-constructing child
destructing zombie
destructing child
constructing child
move-constructing child
destructing zombie
destructing child
关于c++ - 为什么在执行 vector 时会两次调用复制构造函数.push_back,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30358475/