auto_ptrについての念のため前提知識。
C++ではnewで確保したメモリは、使用後にdeleteを呼び出して解放しなければならない。
しかしながら、returnが複数あったり、例外が絡むと解放忘れが起こりえる。
そういった場合には標準ライブラリにあるauto_ptrを使い、
auto_ptrの変数がスコープから消える際に、
自動でポインタの解放処理を行わせる。
実際はいろいろと複雑なことをしているのだろうが、
下記のコードと大筋やっていることは同じである。
#include <iostream> #include <string.h> template<typename T> class My_auto_ptr { private: T *mP; public: My_auto_ptr(T *p = 0) ※1 : mP(p) { std::cout << "constructor" << std::endl; } ~My_auto_ptr() { std::cout << "destructor" << std::endl; delete mP; } // 本筋ではないがこういったものがあると便利である T* operator->() {return mP;} ※2 T& operator*() {return *mP;} ※3 }; int main() { My_auto_ptr <int> hoge = new int(10); return 0; }※1
未初期化を防ぐバグ防止のためである。
※2
オペレータのオーバーロードである。
mPがクラスへの参照であった場合、
ポインタのように見せられる。
hoge->func();
下記と同じである。
(hoge.operator->())->func();
※3
同じく、オペレータのオーバーロードである。
代入を行わせる。
書き換えの可能性があるので参照を返すこと(T &)。
*hoge = 10;
下記と同じである。
hoge.operator*() = 10;
その他
改善すべき点が多々おもいつくだろう。
(改良点1)
delete時は0ポインタを入れて解放するようにした方がいい。
そのためのマクロとしてSAFE_DELETEというものを用意しておくと便利である。
(改良点2)
こういったことをすればhoge1、hoge2で2回deleteされてしまう。
My_auto_ptr
My_auto_ptr
代入を禁止をすればいいだろうか。
しかし関数の引数として使う場合(func(hoge1)など)にコピーされる問題をどうするか。
参照で乗り切るか。
ただし用途によっては参照ではなく実体のフィールドを入れたい場合もある。
その対策として簡易的な参照カウンタなどを作ればいいだろう。