您可以防止在某些类的指针上使用删除运算符。例如:
class Object {
public: void operator delete(void* p) = delete;
};
class Entity : public Object { };
int main(int argc, char const *argv[])
{
Object* o = new Object;
Entity* e = new Entity;
delete o; // compiler error
delete e; // compiler error
return 0;
}
对于所有继承自 Object 的类都无法删除,因为 Object::operator delete 已被删除。不要将此运算符标记为私有,因为它会在派生或实例化 Object 类时产生编译器错误。请注意,我们仍然可以这样做:
::operator delete(o);
这将释放 o 指针但不会调用析构函数。使用一个类来管理 Object 类的生命周期。一个简单的实现是:
class Object {
template<typename type> friend class ptr;
public: void operator delete(void* p) = delete;
};
class Entity : public Object { };
template<typename type>
class Ptr {
public:
Ptr(type* obj) : o(obj){}
~Ptr() { o->~type(); ::operator delete(o); }
private: type* o;
};
int main(int argc, char const *argv[])
{
Object* o = new Object;
Entity* e = new Entity;
// delete o; // error
// delete e; // error
Ptr<Entity> ent = new Entity; // Ptr will delete ent for you.
return 0;
}