3

我有一个类,代理,其成员属性指针指向另一个类的对象,形式:

代理.h

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

代理.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似乎 push_back 试图复制传入的值。由于我在代理类中没有复制构造函数,所以在隐式复制尝试时表单指针会发生什么情况?如果指向的值在编译器生成的隐式复制构造函数中丢失,添加显式复制构造函数会解决错误的访问异常吗?上面的 Agent 类的复制构造函数应该如何实现?这是三法则所描述的前提的一个例子吗?

4

2 回答 2

2

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

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

在 C++11 中,您可以通过持有一个std::unique_ptr<Form>而不是原始指针来解决此问题。在 C++03 中,遵循三的规则

于 2013-03-11T21:44:52.427 回答
1

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

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

于 2013-03-11T21:46:03.647 回答