これは古い回答済みの質問ですが、@Alexandre が「なぜこれをやりたいと思うのですか?」と尋ねたので、今日の午後に検討している使用例を提供できると思いました。
レガシーコード。ネイキッド ポインター Obj*obj を使用し、最後に delete obj を付けます。
残念ながら、オブジェクトをより長く存続させる必要がある場合がありますが、頻繁ではありません。
参照カウントのスマートポインタにすることを検討しています。しかし、どこでも使用する場合は、変更するコードがたくさんあります。ref_cnt_ptr<Obj>
また、裸の Obj* と ref_cnt_ptr を混在させると、最後の ref_cnt_ptr がなくなったときに、Obj* がまだ生きている場合でも、オブジェクトを暗黙的に削除できます。
したがって、explicit_delete_ref_cnt_ptr を作成することを考えています。つまり、明示的な削除ルーチンでのみ削除が行われる参照カウント ポインターです。既存のコードがオブジェクトの有効期間を認識している場所と、オブジェクトをより長く存続させる新しいコードで使用します。
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;
}
}
};
わかりました、そのようなもの。参照カウント ポインター型が、rc された ptr デストラクタで指されているオブジェクトを自動的に削除しないのは少し珍しいことです。しかし、これにより、ネイキッド ポインターと rc されたポインターを混在させることが少し安全になるようです。
しかし、これまでのところ、これを削除する必要はありません。
しかし、それから私は思いつきました: 指しているオブジェクトが参照カウントされていることを知っている場合、たとえば、カウントがオブジェクト内 (または他のテーブル内) にある場合、ルーチン delete_if_rc0 はのメソッドになる可能性があります(スマート) ポインターではなく、pointee オブジェクトです。
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;
}
};
(ところで、コードが正しくないことはわかっています。すべての詳細を追加すると読みにくくなるため、このままにしておきます。)