Vector::push_back(没有复制构造函数的对象)是指针值丢失

vector::push_back on an object without a copy-constructor -- are pointer values lost?

本文关键字:对象 指针 复制 back push Vector 构造函数      更新时间:2023-10-16

我有一个类Agent,它有一个成员属性指针指向另一个类Form的对象:

Agent.h

...//snip includes
class Agent{
private:
  Form* mvForm_ptr;
  ...
public:
  Agent();
  ~Agent();
  ...//snip additional functionality, but no copy-constructor
};

Agent.cpp

#include "Agent.h"
Agent::Agent(){
  mvForm_ptr = new Form();
}
Agent::~Agent(){
  delete mvForm_ptr;
}
...

如您所见,我没有为Agent提供显式的复制构造函数。之后,我像这样使用Agent:

Agent player;
std::vector<Agent> agentsVector;
agentsVector.push_back(player);

这似乎是SIGSEGV崩溃的原因,它的错误报告声称~Agent抛出EXC_BAD_ACCESS异常。仔细阅读vector::push_back,似乎push_back试图复制传入的值。由于我在类代理中没有复制构造函数,因此在隐式复制尝试时表单指针会发生什么?如果在编译器生成的隐式复制构造函数中丢失了指向的值,那么添加显式复制构造函数是否可以解决不良访问异常?如何实现上面的类Agent的复制构造函数?这是"三法则"所描述的前提的一个例子吗?

在隐式复制尝试时表单指针会发生什么?

所发生的是指针数据成员被复制,这意味着原始数据成员和复制数据成员都指向同一个对象,这反过来又意味着当它们的生命周期结束时,它们都将试图删除它。这些删除中只有一个可以成功。另一个导致未定义行为

在c++ 11中,你可以通过保存一个std::unique_ptr<Form>而不是一个原始指针来解决这个问题。在c++ 03中,遵循三个

规则。

由于您没有提供复制或赋值操作符,编译器将为您生成一个,并且指针将被复制,但不复制表单。在每次销毁代理时,您的指针将被释放,并且您将多次释放相同的内存。

一个简单的解决方案是使用shared_ptr来确保仅在没有更多代理时才删除表单。