5

正しい方法でやりたいです。ここで boost::serialization::singleton を公開しているのを見てきました Boost python export singletonですが、それを使用したくありません。代わりに単純なマイヤーズ シングルトンを使用したい。

以下のコードは機能し ますが、 http://www.boost.org/doc/libs/1_43_0/libs/python/doc/v2/reference_existing_object.html#reference_existing_object-spec/の使用 は危険であるとドキュメントに記載されています。

コード:

class Singleton 
{
private:
Singleton(){};

public:
static Singleton & getInstance()
{
    static Singleton instance;
    return instance;
}

int getNumber() { return 5; }
};

そしてモジュールで:

class_<Singleton>("singleton", no_init)
    .def("getInstance", &Singleton::getInstance, return_value_policy<reference_existing_object>()).staticmethod("getInstance")
    .def("getNumber", &Singleton::getNumber)

    ;

それを行う良い方法は何ですか?を使用するreturn_internal_reference<>()と、Python コードの実行中にエラーが発生しました。

4

1 に答える 1

4

コードにはそのようなものがたくさんあります。簡単な方法は考えていませんが、null削除機能を使用して参照からboost :: shared_ptr <>を返すことでそれらを公開しています(コードの一部をshared_ptrと他のものはそうではないので、これは混合物です)。これは非常に良いことではありませんが、メインが残された後にポインタで何もしないようにすると、期待どおりに機能し、落とし穴はありません。

オブジェクトの存続期間はインタープリターよりも存続するため、ここで参照をpythonに戻すときに、問題を恐れる必要はありません。ライブラリは、インタプリタが終了した後にのみ解放されます(デストラクタを呼び出す場合と呼び出さない場合がありますが、エラーなどの場合は全体が存在する場合があります)。したがって、この場合、インタプリタは古典的なmain()関数と考えることができます。

class_<XY, shared_ptr<XY>, boost::noncopyable >("XY",no_init)
  .def("getInstance",&XY::getSharedInstance )
  .staticmethod("getInstance")

struct NullDeleter
{
  void operator()(const void*){}
};

XY& XY::getInstance()
{
  static XY in;
  return in;
}

// This can also be written as a standalone function and added to the python class above.
shared_ptr<XY> XY::getSharedInstance()
{
  return shared_ptr<XY>( &getInstance(), NullDeleter() );
}

または、別の関数に邪魔にならないsharedInstanceを記述して、Pythonパッケージでこれを使用することもできます。

shared_ptr<XY> getSharedInstance()
{
  return shared_ptr<XY>( &XY::getInstance(), NullDeleter() );
}

class_<XY, shared_ptr<XY>, boost::noncopyable >("XY",no_init)
  .def("getInstance",&getSharedInstance )
  .staticmethod("getInstance")
于 2012-09-07T13:50:14.740 に答える