機能:
各種スマートポインタを shared_ptr に変換します。
- 名前空間の自動紹介は行わない事になりました。代わりに using gintenlib::to_shared としてください。
+ 名前空間の自動照会は行わない事になりました。代わりに using gintenlib::to_shared としてください。
+
+ 要求:
+ 一般の P に対する要求は、以下の通り:
+ element_type を持つ。
+ P::element_type get() const; メンバ関数を持つ。
+ デフォルトコンストラクタを呼び出せる。例外を投げない。
+ copy constructable である。その際、内部に格納されているポインタのアドレスが変化してもいい。
+ swap( p1, p2 ) が例外を投げない。
*/
// これを実行すると、このオブジェクトは NULL に再設定される
shared_t to_shared()
{
- using namespace std; // for assert()
+ using namespace std; // for assert, swap
T* p = pt.get();
// いったん仮の to_shared_holder を使って shared_ptr を作る
// これは例外を投げない
to_shared_holder* holder = boost::get_deleter< to_shared_holder >( temp );
- // 作ったばかりの holder の型が不一致なわけない
+ // 作ったばかりの holder の型が不一致なわけないが、一応チェック
assert( holder != 0 );
// これも大丈夫
return temp;
}
- // 一番大事なはずの削除関数・・・だが
- // やってることは特に無し
+ // 削除関数
typedef void result_type;
- void operator()( T* target ) throw ()
+ void operator()( T* )
{
- // 一応、正しいターゲットを削除しているかどうか、チェックする
- using namespace std;
- assert( !pt.get() || pt.get() == target );
+ // ポインタを破棄する
+ Pointer p0;
- // これが呼ばれた後に shared_ptr の働きでこのオブジェクトが破棄され、
- // 同時に pt の有効期限も切れるので、ここでは何もしない
+ using namespace std;
+ swap( pt, p0 );
}
private:
}
hoge( const hoge& )
+ : gintenlib::reference_counter<hoge>()
{
cout << "hoge::hoge( const hoge& );\n";
}
};
// 適当な俺俺スマートポインタを作る
-template<typename T>
-struct oreore_ptr
- : gintenlib::pointer_facade< oreore_ptr<T>, T >
+
+// 深いコピーを行っても格納出来ることを示すため、
+// 簡易版 deep_ptr で試してみる( gintenlib::deep_ptr は専用の to_shared が呼ばれるので)
+#include <gintenlib/pointer_facade.hpp>
+#include <boost/scoped_ptr.hpp>
+template< typename T >
+struct my_deep_ptr
+ : gintenlib::pointer_facade< my_deep_ptr<T>, T >
{
-};
+ // デフォルトコンストラクタ
+ my_deep_ptr() : p() {}
+
+ // ポインタから作るコンストラクタ
+ explicit my_deep_ptr( T* p_ )
+ : p( p_ ) {}
+
+ // コピーコンストラクタ
+ my_deep_ptr( const my_deep_ptr& src )
+ : p( src.p ? new T( *src.p ) : 0 ) {}
+
+ // デストラクタ
+ // scoped_ptr() のおかげで何もしなくていい
+ // ~my_deep_ptr(){}
+
+ // nothrow swap ( for operator= )
+ void swap( my_deep_ptr& other )
+ {
+ p.swap( other.p );
+ }
+ friend void swap( my_deep_ptr& one, my_deep_ptr& another )
+ {
+ one.swap( another );
+ }
+
+ // 代入演算は copy して swap
+ my_deep_ptr& operator=( const my_deep_ptr& src )
+ {
+ my_deep_ptr( src ).swap( *this );
+ return *this;
+ }
+
+ void reset( T* p_ = 0 )
+ {
+ my_deep_ptr( p_ ).swap( *this );
+ }
+
+ // get pointer
+ // これと pointer_facade からいろいろと自動生成
+ T* get() const { return p.get(); }
+
+ private:
+ boost::scoped_ptr<T> p;
+
+}; // class my_deep_ptr<T>
// 汎用版はまだテストしない。 intrusive, auto をチェック
int main()
cout << "scope out: p1, p2\n";
}
+ // ユーザ定義クラス
+ {
+ my_deep_ptr<hoge> p1;
+ PRINT_AND_EXECUTE( p1.reset( new hoge() ) );
+ PRINT_EXPR( p1.get() );
+ boost::shared_ptr<hoge> p2;
+ PRINT_AND_EXECUTE( p2 = gintenlib::to_shared(p1) );
+
+ // ちゃんと深いコピーできているかチェック
+ PRINT_EXPR( p1.get() );
+ PRINT_EXPR( p2.get() );
+
+ // 抜けます
+ cout << "scope out: p1, p2\n";
+ }
+
return 0;
}