OSDN Git Service

今日の作業はここまで
[gintenlib/gintenlib.git] / tests / new_.cc
1 #include "../gintenlib/new_.hpp"
2
3 // 仮テストコードなので
4 // boost.test はまだ使わない。
5 // というより、簡単な使い道を説明する程度のコード。
6
7 #include <iostream>
8 using namespace std;
9
10 // shared_ptr を受け取る関数
11 template<typename T>
12 void hoge( const boost::shared_ptr<T>& ptr )
13 {
14   // 内容は別にどうでもよろしい
15   cout << *ptr << endl;
16 }
17
18 void test1()
19 {
20   // 基本的な使いかた
21   // shared_ptr を受け取る関数があるとする。例えば上の hoge だ。
22   // この手の関数に、新しく作ったオブジェクトを入れたい。
23   
24   // hoge( new int(23) );
25   // こう書ければいいが、生ポインタから shared_ptr への暗黙変換は不可能である。
26   
27   // そこでこう書き、明示的に変換して渡すこととなる。
28   hoge( boost::shared_ptr<int>( new int(23) ) );
29   
30   // これは型名 int が二回使われていて冗長である。ここで new_ を使えば 
31   hoge( gintenlib::new_<int>( 42 ) );
32   // と書ける。多くのプログラマは、これを自然と感じるのではないだろうか。
33   
34   // また、これは例外安全性の観点からも重要である。
35   // 詳しくは http://boost.cppll.jp/HEAD/libs/smart_ptr/shared_ptr.htm#BestPractices を参照。
36   // gintenlib::new_ は、この問題を非常にうまく扱うことが出来る。
37 }
38
39 // また gintenlib::new_ は、それ以外からの構築を禁止するようなクラスを簡単に作成できる。
40 // その一番の使い道は、boost::enable_shared_from_this を使う場合だろう。
41 // gintenlib::new_ 以外で構築できないクラスは、確実に shared_ptr に格納されるからである。
42 // これらには二つの実装法がある。順に見てみよう。
43
44 #include <boost/enable_shared_from_this.hpp>
45
46 // 実装1
47 struct force_shared1
48   : boost::enable_shared_from_this<force_shared1>
49 {
50   ~force_shared1() throw () {}
51   
52   void foo()
53   {
54     cout << "force_shared1::foo();\n";
55   }
56   
57  private:
58   // private に全てのコンストラクタを置き、一般からの構築を禁止
59   force_shared1() {}
60   // その上で gintenlib::new_core_access 構造体を friend に指定する
61   friend class gintenlib::new_core_access;
62   
63 };
64
65 // 実装2
66 struct force_shared2
67   : boost::enable_shared_from_this<force_shared2>,
68     gintenlib::enable_static_new_<force_shared2>  // これを指定する
69 {
70   ~force_shared2() throw () {}
71   
72   // 適当にメンバを置く
73   void foo();
74   void bar();
75   
76   // enable_static_new_<クラス名> から継承させることで、
77   // new_ による構築は、そのクラスの静的関数 new_ を通して行われるようになる
78   static boost::shared_ptr<force_shared2> new_()
79   {
80     cout << "force_shared2::new_();\n";
81     return boost::shared_ptr<force_shared2>( new force_shared2() );
82   }
83   // 当然複数の new_ を置ける
84   static boost::shared_ptr<force_shared2> new_( int )
85   {
86     cout << "force_shared2::new_( int );\n";
87     return boost::shared_ptr<force_shared2>( new force_shared2() );
88   }
89   
90  private:
91   // 同様に private に全てのコンストラクタを置き、一般からの構築を禁止
92   force_shared2() {}
93     
94 };
95
96 // 使い方
97 void test2()
98 {
99   // 使う分にはその差を意識することはない。
100   boost::shared_ptr<force_shared1> p1 = gintenlib::new_<force_shared1>();
101   p1->foo();
102   
103   boost::shared_ptr<force_shared2> p2 = gintenlib::new_<force_shared2>(),
104                                    p3 = gintenlib::new_<force_shared2>( 0 );
105 }
106
107 int main()
108 {
109   test1();
110   test2();
111   
112 }