![](/img/trans.png)
[英]override a C++ virtual function within Python with Boost.python?
[英]Virtual inheritance C++ and boost python
在我正在开发的游戏中,我有两个C ++类(ICollidable和Sprite),它们实际上都继承了另一个名为Object的C ++类,这是因为其属性Position和Size。 我用boost python将这三个类暴露给python。 python中的Player类构造函数如下所示:
class Player(Game.ICollidable, Game.Sprite, Game.IKeyboardListener, Game.IEntity):
def __init__(self):
Game.IKeyboardListener.__init__(self)
Game.IEntity.__init__(self)
Game.ICollidable.__init__(self)
Game.Sprite.__init__(self)
问题在于,当Sprite 初始化在ICollidable的初始化之前出现时,Sprite位置无法正确运行,并且我无法在屏幕上重新放置Sprite。 我认为正在发生的事情是该职位与Sprite和ICollidable有单独的实例,这是我认为在制作ICollidable类之前会发生的事情。
我已经尝试了多种方法来尝试解决此问题,并搜寻了互联网以找到解决此类问题的方法,但是我空手而归。 任何建议,解决方案或提示将不胜感激。
编辑:
这些是我C ++类的python绑定:
class_<Object>("GameObject")
.def_readwrite("Pos", &Object::pos)
.def_readwrite("Size",&Object::size)
;
class_<Sprite, bases<Object>>("Sprite", init<>())
// Sprite(TexID, Pos)
.def(init<GLuint, glm::vec2>())
// ----------------------------
.def_readwrite("TexId", &Sprite::texid)
;
class_<ICollidableWrap, bases<Object>,boost::noncopyable>("ICollidable", init<>())
//.def("Pos", &ICollidable::Object::pos)
.def("Test", pure_virtual(&ICollidable::Test))
.def("OnCollision",pure_virtual(&ICollidable::OnCollision))
;
两种语言都可以解决钻石问题 ,但是它们使用不同的方法。 C ++通过虚拟继承消除了歧义,从而使单个子对象得以共享。 另一方面,Python通过单调超类线性化查找消除了歧义。 由于Python继承不会导致C ++类型共享一个子对象,因此当Python类从两个共享一个公共虚拟基础的公开C ++类继承时,Boost.Python将需要模拟C ++虚拟继承。 不幸的是,据我所知,Boost.Python不支持这种情况,因为没有检查提供给boost::python::bases<...>
的类型的虚拟继承。
尽管不具有可伸缩性,并且可能表明它可能值得研究基于组合的解决方案,但一个简单的继承解决方案是公开从ICollidableWrap
和Sprite
继承的CollidableSprite
C ++类,然后使Python类从CollidableSprite
继承。
这是一个基本示例,其中类C
从B
继承,而类A
从V
继承:
#include <boost/python.hpp>
/// @brief Mock up forming the following multiple inheritance
/// structure:
///
/// .-->[ V ]<--.
/// | |
/// [ A ] [ B ]
/// | |
/// '---[ C ] --'
struct V
{
V() : x(0) {}
virtual ~V() {}
unsigned int x;
};
struct A : virtual public V {};
struct B : virtual public V {};
struct C : public A, public B {};
/// @brief Functions that force an object's hierarchy chain to be
/// split, disambiguating access to V.x.
void print_a(A& a) { std::cout << a.x << std::endl; }
void print_b(B& b) { std::cout << b.x << std::endl; }
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
// Expose hierarchy.
python::class_<V>("V", python::no_init)
.def_readwrite("x", &V::x)
;
python::class_<A, python::bases<V> >("A");
python::class_<B, python::bases<V> >("B");
python::class_<C, python::bases<A, B> >("C");
// Expose helper functions.
python::def("print_a", &print_a);
python::def("print_b", &print_b);
}
互动用法:
>>> import example
>>> class PyC(example.A, example.B):
... def __init__(self):
... example.A.__init__(self)
... example.B.__init__(self)
...
>>> c = PyC()
>>> example.print_a(c)
0
>>> example.print_b(c)
0
>>> c.x = 42
>>> example.print_a(c)
0
>>> example.print_b(c)
42
>>> class PyC(example.C):
... pass
...
>>> c = PyC()
>>> example.print_a(c)
0
>>> example.print_b(c)
0
>>> c.x = 42
>>> example.print_a(c)
42
>>> example.print_b(c)
42
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.