我有一个类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描述的前提的一个例子吗?
答案 0 :(得分:2)
隐式复制尝试时Form指针会发生什么?
指针数据成员被复制,这意味着原始和副本都指向同一个对象,这反过来意味着他们都会在生命结束时尝试删除它。这些删除中只有一个可以成功。另一个导致未定义的行为。
在C ++ 11中,您可以通过按住std::unique_ptr<Form>
而不是原始指针来解决此问题。在C ++ 03中,按照rule of three。
答案 1 :(得分:1)
由于您没有提供副本或赋值运算符,编译器将为您生成一个并且指针将被复制但不会复制表单。在代理的每次破坏时,您的指针都将被释放,并且您将多次释放相同的内存。
一个简单的解决方法是使用shared_ptr确保仅在没有代理时才删除表单。