我一直在为脚本语言编写包装库(部分用于学习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()
以使用例更清晰
答案 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;
}