繁体   English   中英

虚拟继承C ++和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<...>的类型的虚拟继承。

尽管不具有可伸缩性,并且可能表明它可能值得研究基于组合的解决方案,但一个简单的继承解决方案是公开从ICollidableWrapSprite继承的CollidableSprite C ++类,然后使Python类从CollidableSprite继承。


这是一个基本示例,其中类CB继承,而类AV继承:

#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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM