我有一个使用很多类的C ++项目。主要的是'sso::Object
'(每个类都在'sso'命名空间中),这个类派生到其他一些类中,但是一个是抽象的:'sso::Drawable
'。
这个类有两个纯虚拟方法“sso::Drawable::set_opacity
”和“sso::Drawable::raw_draw
”,并且它被派生到其他类中,例如实现这两种方法的“sso::View
”。
整个项目在C ++中使用时工作正常,但我也想在Python中使用它,所以我创建了一个Boost.Python模块:
class DrawableWrapper : public sso::Drawable , public wrapper<sso::Drawable> {
public:
void set_opacity(byte opacity) { this->get_override("set_opacity")(opacity); }
void raw_draw(const sso::Rect &rect,sso::Target &target,const sso::Position &position) const {
this->get_override("raw_draw")(rect,target,position);
}
};
BOOST_PYTHON_MODULE(sso) {
class_<DrawableWrapper,boost::noncopyable> ("Drawable",init<>())
.add_property ("opacity",&sso::Drawable::get_opacity)
// python_sso_getter & python_sso_setter_* are only used for an easier access to accessors
.add_property ("position",python_sso_getter<sso::Drawable,sso::Position,&sso::Drawable::get_position>,python_sso_setter_1_const<sso::Drawable,sso::Position,&sso::Drawable::set_position>)
.def("raw_draw",pure_virtual(&sso::Drawable::raw_draw))
;
class_<sso::View,bases<sso::Drawable> > ("View",init<>())
.def("insert",python_sso_setter_1<sso::View,sso::Drawable*,&sso::View::insert>)
.def("remove",&sso::View::erase)
;
}
这段代码编译没有错误,但是当我在Python中执行这些行时:
myview = sso.View()
print myview
我得到了这个输出:
&lt; sso.View对象位于0x7f9d2681a4b0&gt;
但是我的C ++调试器告诉我变量'v'(python'myview')是一个'sso::Object
'实例,而不是'sso::View
'实例。调用sso::View::View()
但变量类型不是视图,我不知道为什么。你对此有什么想法吗?你做过类似的事情并找到了一种方法让它发挥作用吗?
我使用Python2.7和Boost.Python1.49以及gcc版本4.6.1
编辑:我犯了一个错误:sso::Drawable
不是从sso::Object
继承,而是sso::View
做的(=多重继承)。
答案 0 :(得分:1)
python的输出<sso.View object at 0x7f9d2681a4b0>
只是python告诉你它认为对象类型被调用了什么,它与在C ++级别创建的实际对象类型无关。
正如你已经告诉boost python将对象公开为sso.View
那么python会将其视为。如果您要更改代码以将std::string
公开为sso.View
,那么python在您创建后仍会报告<sso.View object at 0x7f9d2681a4b0>
。
同样,如果你要将C ++中的"View"
更改为"BlahDeBlah"
,那么python会将对象报告为<sso.BlahDeBlah object at 0x7f9d2681a4b0>
(当然你也必须通过{{{}创建它。 1}}
除此之外,我发现您发布的代码没有任何问题。 sso.BlahDeBlah()
是否继承自sso::View
?如果是这种情况,并且您已经见证了sso::Object
被调用,那么我认为当它告诉您对象类型为sso::view::View()
时,您可能只是误解了调试器。也许它在你正在调试的时候有一个指向基类或类似东西的指针?
从python中调用sso::Object
或myview.insert
时会发生什么?
myview.remove
只是返回实现您在调用{{1时所使用的函数的类型}}。这肯定会解释为什么你在typeid()
时得到typeid()
但在其他函数中得到不同答案。
无论如何,我一直在仔细研究文档,我认为你的问题实际上是你提供了覆盖sso::View
方法的能力,但你实际上没有用任何方法覆盖它
如果你看一下insert
boost :: python函数at the bottom of this file的解除,你会看到一条评论:
raw_draw
所以你所看到的只是预期的行为。如果为pure_virtual
中的//
// Passed a pointer to member function, generates a def_visitor which
// creates a method that only dispatches to Python if the function has
// been overridden, either in C++ or in Python, raising a "pure
// virtual called" exception otherwise.
//
或继承自它的python类提供覆盖,则不应再出现此错误。