0

私はスクリプト言語用のラッピング ライブラリに取り組んできました (一部は c++11 の機能を学習するため、一部は特定のニーズのため)。発生した問題の 1 つは、継承されたオブジェクトをスクリプト言語にエクスポートすることです。

問題は、関数の呼び出しにラップされたクラスのプロキシ オブジェクトを使用することです。具体的には、関数が を受け取る場合、Foo *使用されているスクリプト言語のオブジェクト プロキシを適切にキャストする必要があります。

オブジェクト プロキシを適切にモデル化するには、(私が考えることができる) 2 つの方法があります。

template <class T>
struct ObjectProxy {
   T *ptr;
};

また:

struct WrappedClass {
  virtual ~WrappedClass() {}
};

struct ObjectProxy {
  WrappedClass *ptr;

  template <typename T>
  boost::shared_ptr<T> castAs() {
    return boost::dynamic_pointer_cast<T>(instance);
  }
};

ObjectProxy最初のバージョンの問題は、どの型が指されているかを事前に知る必要があることです。残念ながら、これに対する簡単な解決策はありません (私の以前の質問の多くを参照してください)。調査の結果、これを行う一般的なライブラリ (boost::python、LuaBind など) のほとんどは、適切なキャストを可能にするために、すべてのクラス関係のグラフを保持しているようです。

2 番目の方法では、これらすべてを実行する必要はありませんが、ラップするすべてのクラスが WrappedClass から継承する必要があるという制約が追加されます。

これが私の質問です: 2 番目のアプローチで、ユーザーに少し迷惑をかける以外に、大きな問題を考えられる人はいますか? 特定のクラスを作成していなくても、いつでもサブクラス化できるはずです。たとえば、 classFooを提供するライブラリがある場合、次のようにすることができます。

class FooWrapped: public Foo, public WrappedClass {};

これにより、ユーザーにとって少しシームレスではなくなりますが (これを自動化する方法を検討してきましたが)、独自のバリアントを作成する必要がなく、組み込みの dynamic_cast に依存できることを意味します。

編集

castAs()ユースケースを明確にするために追加

4

1 に答える 1

0

あなたの問題は、 boost::anyが解決するように設計されたもののように聞こえます。このソリューションは基本的に2つのアイデアを組み合わせたものです:(コードはテストされていません)

struct ObjectProxyBase {
  virtual ~ObjectProxyBase() {}
};

template <class T>
struct ObjectProxy : public ObjectProxyBase {
   T *ptr;
};

template <class T>
T *proxy_cast(ObjectProxyBase *obj) {
    auto ptr = dynamic_cast<ObjectProxy<T> *>(obj);
    if (!ptr)
        return nullptr;

    return ptr->ptr;
}
于 2013-01-10T06:04:39.193 に答える