これは古く、答えられた質問ですが、@ Alexandreは「なぜ誰もがこれをしたいのですか?」と尋ねました。
レガシーコード。裸のポインターObj * objを使用し、最後に削除objを指定します。
残念ながら、オブジェクトをより長く存続させるために、頻繁にではなく時々必要があります。
参照カウントのスマートポインターにすることを検討しています。しかし、どこでも使用する場合、変更するコードはたくさんありますref_cnt_ptr<Obj>
。また、ネイキッドObj *とref_cnt_ptrを混在させると、Obj *がまだ存在していても、最後のref_cnt_ptrがなくなるとオブジェクトが暗黙的に削除されます。
したがって、explicit_delete_ref_cnt_ptrの作成を検討しています。つまり、削除が明示的な削除ルーチンでのみ行われる参照カウントポインター。既存のコードがオブジェクトの存続期間を知っている1つの場所で使用することと、オブジェクトをより長く存続させる新しいコードで使用すること。
explicit_delete_ref_cnt_ptrが操作されるときの参照カウントの増分および減分。
ただし、explicit_delete_ref_cnt_ptrデストラクタで参照カウントがゼロであると見なされた場合は解放されません。
明示的な削除のような操作で参照カウントがゼロであると見なされた場合にのみ解放されます。例:
template<typename T> class explicit_delete_ref_cnt_ptr {
private:
T* ptr;
int rc;
...
public:
void delete_if_rc0() {
if( this->ptr ) {
this->rc--;
if( this->rc == 0 ) {
delete this->ptr;
}
this->ptr = 0;
}
}
};
OK、そのようなもの。rc'ed ptrデストラクタでポイントされているオブジェクトを自動的に削除しない参照カウントポインタ型を持つのは少し珍しいことです。しかし、これにより、ネイキッドポインターとrc'edポインターの混合が少し安全になるようです。
しかし、これまでのところ、これを削除する必要はありません。
しかし、それが私に起こりました:オブジェクトが指すオブジェクト(参照先)が参照カウントされていることを知っている場合、たとえば、カウントがオブジェクト(または他のテーブル)内にある場合、ルーチンdelete_if_rc0は、 (スマート)ポインタではなく、指示先オブジェクト。
class Pointee {
private:
int rc;
...
public:
void delete_if_rc0() {
this->rc--;
if( this->rc == 0 ) {
delete this;
}
}
}
};
実際には、メンバーメソッドである必要はまったくありませんが、無料の関数である可能性があります。
map<void*,int> keepalive_map;
template<typename T>
void delete_if_rc0(T*ptr) {
void* tptr = (void*)ptr;
if( keepalive_map[tptr] == 1 ) {
delete ptr;
}
};
(ところで、私はコードが正しくないことを知っています-すべての詳細を追加すると読みにくくなるため、このままにしておきます。)
delete this
、クラスとそのクラスのオブジェクトの作成に使用される割り当てメソッドとの間に密結合を作成した場合です。OOPの最も基本的なことは、呼び出し元が何をしているかを知らないか気にしない自律クラスを作成することであるため、これは非常に悪いOO設計です。したがって、適切に設計されたクラスは、それがどのように割り当てられたかを認識したり、気にする必要はありません。なんらかの理由でこのような特殊なメカニズムが必要な場合は、実際のクラスの周りにラッパークラスを使用して、ラッパーに割り当てを処理させる方が良いと思います。