在包装类的c ++ 11中强制继承类 - 这是件坏事吗?

时间:2013-01-08 16:12:31

标签: c++ c++11 multiple-inheritance wrapping

我一直在为脚本语言编写包装库(部分用于学习c ++ 11功能,部分用于特定需求)。已经出现的一个问题是将继承的对象导出为脚本语言。

问题涉及使用包装类的代理对象来调用函数。具体来说,如果一个函数需要Foo *,那么必须正确地使用来自任何脚本语言的对象代理。

有两种方法(我能想到)适当地建模对象代理:

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等)都保留了所有类关系的图形,以便进行适当的转换。

第二种方法避免必须完成所有操作,但确实添加了约束,即您包装的每个类都必须从WrappedClass继承。

这是我的问题:除了对用户有点烦恼之外,第二种方法可以让人想到任何重大问题吗?即使您没有创建特定的类,您也应始终能够对其进行子类化。例如,如果你有一些库提供类Foo,那么你可以这样做:

class FooWrapped: public Foo, public WrappedClass {};

这确实让用户的事情变得更加无缝(虽然我一直在研究自动化的方法),但它确实意味着你可以依赖内置的dynamic_cast而不必编写自己的变体。 / p>

修改

添加了castAs()以使用例更清晰

1 个答案:

答案 0 :(得分:0)

您的问题听起来像boost::any旨在解决的问题。该解决方案基本上结合了您的两个想法:(代码未经测试)

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;
}