特定のクラスのポインターでの削除演算子の使用を防ぐことができます。例えば:
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::operator の削除が削除されたため、Object から継承するすべてのクラスを削除できません。Object クラスを派生またはインスタンス化するときにコンパイラ エラーが発生するため、この演算子をプライベートとしてマークしないでください。まだそうすることができることに注意してください。
::operator delete(o);
o ポインターは解放されますが、デストラクタは呼び出されません。クラスを使用して、オブジェクト クラスの寿命を管理します。簡単な実装は次のようになります。
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;
}