gintenlib::new_ を使う

gintenlib::new_ は、新しくオブジェクトを new 演算子を用いて生成し、そのアドレスを boost::shared_ptr に格納して返す関数テンプレートです。
これだけならば boost::make_shared を使うべきなのですが、gintenlib::new_ には boost::make_shared に存在しない利点があります。アクセス制御機能です。
gintenlib::new_ 関数からの new 演算子呼び出しは、常に gintenlib::new_core_access クラスから行われます。つまり、コンストラクタを private にした上で gintenlib::new_core_accessfriend 宣言することで、 gintenlib::new_ を使うことでしか生成することのできないクラスを作れるのです。
無論、 gintenlib::new_ を使わなくても、生成用の static 関数を作ることで、同じ機能は再現することが出来ます。
ですが、生成用の static 関数なんて、文面は決まりきったものであり、わざわざ定義するのは面倒というもの。 gintenlib::new_ を使えば、その煩雑さを取り除くことができます。
他にも、「他のオブジェクトと全く同じ表現で構築できる」というメリットもありますし、何より、
xxx::make_xxx( arglist )gintenlib::new_( arglist ) ならば、好みにもよりますが、後者のほうが格好いいでしょう?
「でも、この方法だと、全ての private コンストラクタを公開しちゃうじゃないか。流石にそれはちょっと・・・」と思うかもしれません。が、心配は無用です。
そういう場合は、 gintenlib::enable_static_new_ を使いましょう。使い方は、

struct hoge
  : gintenlib::enable_static_new_<hoge>
{
  // 構築。 public に置いているが、 gintenlib::new_core_access を friend 宣言すれば
  // private に置いてもよくなる。まー普通に考えて一般公開しない手ないのですが
  static boost::shared_ptr<hoge> new_( /* args */ )
  {
    return boost::shared_ptr<hoge>( new hoge( /* args */ ) );
  }
  // なお gintenlib::new_ 的には hoge* を返してもOKですが、
  // 生ポインタ返す生成関数を public に置く意味は不明。非推奨です。
  
  
  // メソッドとか適当に
  
  
 private:
  // 構築を private に
  hoge( /* args */ );
  // コピーも禁止
  hoge( const hoge& );
  
  // メインのほかに private なコンストラクタを作っても
  // gintenlib::new_ は static 関数の new_ を優先するので問題ない
  
  // メンバとか適当に
  
};

以上。C++ プログラマにとっては割とおなじみの記法ですね。
こうしておくことで、一般的なオブジェクトと全く同じように、

boost::shared_ptr<int>  p1 = gintenlib::new_<int>();
boost::shared_ptr<hoge> p2 = gintenlib::new_<hoge>();

って感じに記述できます。なくてもいいけどあれば少し便利でしょう?


以下はライブラリの細かい仕様ですので、読んでも読まなくても:

gintenlib::new_ 仕様

収録ヘッダ
<gintenlib/new_.hpp>
名前空間
gintenlib
ライブラリのリンク
必要なし
namespace gintenlib
{
  // new_ の戻り値のポインタ型(現在は boost::shared_ptr 一択)
  template<typename T>
  struct ptr
  {
    typedef boost::shared_ptr<T> type;
  };
  
  // このクラスから継承することで、gintenlib::new_ からは、
  // コンストラクタではなく static の new_ 関数が呼ばれるようになる
  template<typename Derived >
  struct enable_static_new_ {};
  
  // 上のクラスを継承しているかどうかを判断するクラス
  template<typename T>
  struct enable_if_enabled_static_new_
    : boost::enable_if< boost::is_base_of< enable_static_new_<T>, T > > {};
  
  
  // クラスの private メンバアクセス用のクラス。
  // コンストラクタないし new_ 静的関数を private においた上で、
  // friend class gintenlib::new_core_access; 
  // とすれば、 new_ を介してしか製作できないクラスになる。
  class new_core_access;
  
  
  // 関数オブジェクト版 new_(コンストラクタ版)
  template<typename T>
  struct new_ptr
  {
    typedef typename ptr<T>::type result_type;
    
    // 実際の機能。 new して ptr<T>::type でくるむ
    result_type operator()() const;
    template<typename A1>
    result_type operator()( const A1& arg1 );
    template<typename A1, typename A2>
    result_type operator()( const A1& arg1, const A2& arg2 );
    // 以下、引数の個数は GINTENLIB_ARG_COUNT (=10) 個まで対応
  
  };
  
  
  // 本体
  template<typename T>
  inline typename ptr<T>::type new_();
  template<typename A1>
  inline typename ptr<T>::type new_( const A1& arg1 );
  template<typename A1, typename A2>
  inline typename ptr<T>::type new_( const A1& arg1, const A2& arg2 );
  // これも同様に引数は GINTENLIB_ARG_COUNT (=10) 個まで対応
  
} // namespace gintenlib
gintenlib::ptr メタ関数
// new_ の戻り値のポインタ型(現在は boost::shared_ptr 一択)
template<typename T>
struct ptr
{
  typedef boost::shared_ptr<T> type;
};
機能
gintenlib::new_ の機能(ファンクタ、関数両方)によって作られるポインタの型を指定する。
戻型
boost::shared_ptr<T>。 ゆくゆくは T の型によって生成されるポインタを可変に出来るようにする可能性有り( gintenlib::reference_counter<T> から派生された場合は boost::intrusive_ptr<T> にする等)。 ただしその変更は、互換性の為、メジャーバージョンアップ時にのみ行うとする
enable_static_new_<T> クラステンプレート
template<typename Derived >
struct enable_static_new_ {};
機能
クラス T を作る際、 enable_static_new_<T> から public 継承させることで、 gintenlib::new_ の機能(ファンクタ、関数両方)によって呼ばれる関数を、デフォルトの new 演算子から、T の静的関数 T::new_ に変更する。
補足
gintenlib::new_ (ファンクタ、関数両方)は、あくまでも T 型が enable_static_new_<T> 型から派生されているときのみ、new 演算子ではなく new_ 静的関数を呼び出す。 たとえ T の基底クラス Baseenable_static_new_<Base> を継承していても、T の gintenlib::new_ 呼び出しには、一切関係しない。
new_core_access クラス
class new_core_access;
機能
gintenlib::new_ の機能(ファンクタ、関数両方)によって呼ばれる関数( new 演算子か、T の静的関数 T::new_ )は、このクラスを経由して呼ばれる。
これらの関数を private に置き、このクラスを friend 宣言することにより、 gintenlib::new_ 以外からのオブジェクト構築を禁止できる。
補足
このクラスに用意された全ての機能は、 gintenlib::new_ からしか呼ぶことが出来ない。
本体
// new 演算子を呼び出して ptr<T>::type でくるむ
template<typename T>
inline typename ptr<T>::type new_();

template<typename A1>
inline typename ptr<T>::type new_( const A1& arg1 );

template<typename A1, typename A2>
inline typename ptr<T>::type new_( const A1& arg1, const A2& arg2 );

// 以下、引数は GINTENLIB_ARG_COUNT (=10) 個まで対応


// 関数オブジェクト版
template<typename T>
struct new_ptr
{
  typedef typename ptr<T>::type result_type;
  
  // new_ 関数と全く同じである
  result_type operator()() const;
  // 多引数版も同様に用意
};
機能
指定された引数で new 演算子(あるいは T::new_ 関数)を呼び出し、ptr<T>::type のコンストラクタに渡す。
戻値
出来た ptr::type 型のオブジェクト
例外
TのコンストラクT( arguments ) あるいはTの静的関数 T::new_( arguments ) が投げうる全ての例外、および std::bad_alloc を投げる可能性がある。呼ばれるコンストラクタないし静的関数が例外安全ならば、 gintenlib::new_ も同様に例外安全となる。
備考

このライブラリの基本機能は、 boost::make_shared と全く同様である。よって、enable_static_new_new_core_access の機能を使わないのならば、 boost::make_shared を使うべきである。