我一直在为脚本语言开发一个包装库(部分是为了学习 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 而不必编写自己的变体。
编辑
添加castAs()
以使用例更清晰