gpt4 book ai didi

c++ - 为什么在执行 vector.push_back 时复制构造函数被调用两次

转载 作者:搜寻专家 更新时间:2023-10-31 02:22:23 25 4
gpt4 key购买 nike

我有一个 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com