struct Abstract{
virtual void methodA() = 0;
};
struct Test : public Abstract{
virtual void methodA(){
printf("Test message");
}
};
class Foo{
Abstract* abs; //I made it this way so that an instance of Foo
//can easily switch between any class that implements
//Abstract
public:
virtual ~Foo(){
delete abs; //free abs
}
void setAbs(Abstract* a){
abs = a; //is there any other way to do this?
}
void changeAbs()//method to switch abs
void show(){
abs->methodA();
}
};
int main(){
Test *test = new Test();
// Test test; //local instantiation will throw a segmentation fault
//because abs is freed in the desctructor of Foo
Foo foo;
foo.setAbs(test);
foo.show();
// delete test; //using a pointer is fine unless freed
return 0;
}
我担心的是:
如果我不在析构函数中释放abs并且用户忘记释放实现Abstract的对象,或者如果用户以这种方式执行setAbs(new Test())
,则会有泄漏。
如果我在析构函数中释放abs,如果用户在本地实例化 Test 或者他使用指针并最终将其自行删除,则会抛出分段错误。
Abstract abs
也是不允许的,因为它是一个抽象类
我想将setAbs()更改为:
void setAbs(Abstract* a){
abs = new Abstract(*a); //but copying like a normal class doesn't work on abstract classes
}
我的问题是,有没有其他方法来实现setAbs(),以便它将传递参数的副本?
如果没有别的办法,我会让释放成为用户的工作。
答案 0 :(得分:4)
这里的根本问题是你没有明确谁拥有这个记忆。
如果你的类拥有它,那么在你的析构函数中释放是安全的。好吧,不是你写的方式,而是理论上的。阅读The Rule of Three。
如果您的班级不拥有指针,那么,请不要取消分配它。解除分配并不属于您,所以请使用它,不要再使用它。
处理内存的安全方法是隐式执行合同,确定谁负责什么。如果用户继续前进,delete
指针,那么告诉他们停止;这不是他们的事。您可以使用std::unique_ptr
指针和get()
函数执行相同操作。班级不会阻止你,怎么可能?如果你自己拍脚,它并不在乎。 RTFM。
说到std::unique_ptr
...为什么不使用它(或std::shared_ptr
如果合适的话)?这是一个已解决的问题,无需在此处提出您自己的解决方案。