所以我正在从一个“拥有”的对象模型迁移到我正在做的项目中的“托管”对象模型。目前要做一件新的事情
Thing *thing = new Thing();
并摆脱它并摧毁它所有者
delete thing
现在有很多“删除东西”,其中很多都是从一个删除 Thing指针的超类因为超类有一个虚析构函数。
现在,在托管模型中,有一个带有虚拟析构函数的基类,管理器将删除它。用户应该在其上调用“发布” NOT delete。
所以我想以某种方式在编译时拒绝“删除事物”作为编译时错误。 由于基础上的虚拟析构函数,使析构函数“受保护”似乎不起作用。它至少需要保护子类(我认为)。
有人有什么想法吗?
答案 0 :(得分:6)
您需要在基础和子类上保护析构函数。它应该可以正常工作。
例如,下面的代码会为delete
行生成编译时错误。
class A
{
protected:
virtual ~A() {}
};
class B : public A
{
protected:
virtual ~B() {}
};
int main()
{
B* b = new B;
A* a = new B;
delete b;
delete a;
return 0;
}
答案 1 :(得分:2)
不确定;在您的班级中覆盖operator delete
,并将其设为私有:
struct Foo
{
private:
void operator delete(void*); // no body (never called)
};
答案 2 :(得分:0)
这里有许多相互矛盾的目标。您是否试图限制delete
在单一类型或整个类hieararchy上的使用?我认为您需要考虑使用自定义分配/释放功能(也称为opeartor new
和operator delete
)。特别是,您希望您的对象拥有自己的operator new
和operator delete
函数(可能带有额外的参数),以确保正确分配和释放对象。
我不会在这里解释这些函数的使用,因为编写正确的(例如异常安全等)分配/解除分配函数并不是最简单的任务,并且还有一些额外的困难需要警惕的。结果,你最好找到一篇关于写作的好文章(而且我不知道有哪一个,对不起)。
答案 3 :(得分:0)
好的 - 是的,如果我在基类上覆盖operator delete,如果会导致delete失败,那么它需要在虚拟析构函数完成时调用它。
在我的情况下,我还必须确保com中IUnknown等效的基础“对象”接口具有受保护的析构函数和构造函数,因为智能指针对其中一个执行隐式转换,这将完美地传递给删除并编译!!! (并使应用程序崩溃)
所以我有
class ObjectInterface
protected:
~ObjectInterface();
public:
virtual int method1() = 0;
...
};
class ObjectBase
: public ObjectInterface
, public ObjectImpl // has virtual destructor on it
{
protected:
static void operator delete(void *p) { ::operator delete(p); }
public:
int method1(); // default impl
};
class MyObject
: public ObjectBase
{
protected:
MyObject();
~MyObject();
public:
static SharedPointer<MyObject> create()
{
return(SharedPointer<MyObject>(new MyObject());
}
};
SharedPointer<MyObject> sp = MyObject::create();
MyObject *mo = sp;
sp = NULL; // fine does actual delete inside ObjectImpl
delete sp; // compile error
delete mo; // compile error