shared_ptrの実装5
shared_ptr< void >で任意のインスタンスをdeleteする
前回のshared_ptrの実装4 - while( c++ );で
shared_ptr< void > a( new int( 100 ) );
とすると、デストラクタで正しくdeleteされません。今日はこれを解決しましょう。
問題になっているのは
- delete void*;
です。型がわからないとdeleteできません。
template < typename T > class shared_ptr { ... public: explicit shared_ptr( T* ptr ) : ptr( ptr ) , count( ptr ) {} ... };
- コンストラクタでT*を渡しているので、中の人shared_countが管理しているptrがT*になってしまう。
ということは、任意の型のポインタを保持するために、コンストラクタをテンプレートにすればよいわけですね。
template < typename T > class shared_ptr { ... public: template < typename U > explicit shared_ptr( U* ptr ) : ptr( ptr ) , count( ptr ) {} ... };
これだけでOKです。クラスを渡してもちゃんとデストラクタが呼ばれてます。
class Hoge { public: ~Hoge(){ cout << "~Hoge()" << endl; } }; shared_ptr< void > a( new Hoge );
さらに、派生クラスのポインタを渡すことが可能になります。
class Hoge { public: ~Hoge(){ cout << "~Hoge()" << endl; }//virtualが付いていなくても良い }; class Piyo : public Hoge { public: ~Piyo(){ cout << "~Piyo()" << endl; } }; shared_ptr< Hoge > a( new Piyo );
アップキャスト
同様にコピーコンストラクタもテンプレートにしましょう。
template < typename T > class shared_ptr { ... public: template < typename U > shared_ptr( shared_ptr< U > const& sp ) : ptr( sp.ptr ) , count( sp.ptr ) {} ... };
コンパイルすると、
error C2248: sahred_ptr<T>::ptr : privateメンバにアクセスできません。
怒られました。。。
template
template < typename T > class shared_ptr { template < typename U > friend class shared_ptr; ... };
これで、アップキャストも可能になりました。
shared_ptr< Piyo > a( new Piyo ); shared_ptr< Hoge > b = a; shared_ptr< void > c = a;
ポインタらしくなってきましたね。