没有复制构造函数的对象上的vector :: push_back - 指针值丢失了吗?

时间:2013-03-11 21:42:40

标签: c++ memory-management vector stl

我有一个类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 player;
std::vector<Agent> agentsVector;
agentsVector.push_back(player);

这似乎是SIGSEGV崩溃的原因,其错误报告声称~Agent正在抛出EXC_BAD_ACCESS异常。读取vector :: push_back here似乎push_back尝试复制传入的值。由于我在类Agent中没有复制构造函数,因此在隐式复制尝试时,Form指针会发生什么?如果在编译器生成的隐式复制构造函数中丢失了指向的值,那么添加一个显式的复制构造函数会解决错误的访问异常吗?如何实现上面的类Agent的复制构造函数?这是Rule of Three描述的前提的一个例子吗?

2 个答案:

答案 0 :(得分:2)

  

隐式复制尝试时Form指针会发生什么?

指针数据成员被复制,这意味着原始和副本都指向同一个对象,这反过来意味着他们都会在生命结束时尝试删除它。这些删除中只有一个可以成功。另一个导致未定义的行为

在C ++ 11中,您可以通过按住std::unique_ptr<Form>而不是原始指针来解决此问题。在C ++ 03中,按照rule of three

答案 1 :(得分:1)

由于您没有提供副本或赋值运算符,编译器将为您生成一个并且指针将被复制但不会复制表单。在代理的每次破坏时,您的指针都将被释放,并且您将多次释放相同的内存。

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