【问题标题】:c++ Pure virtual functions dependent on derived classesc++纯虚函数依赖于派生类
【发布时间】:2018-05-02 15:08:51
【问题描述】:

我正在开发一个边界框/碰撞检测系统,我正在使用不同类型的边界体,就像所有边界体一样派生相同的基类,然后使用纯虚函数强制所有派生类实现基本功能喜欢

  • isCollidingWith(BoudingBox)

但这是给我带来麻烦的地方:我不希望他们为每个 BoudingVolume 类型实现一个函数。所以如果我有一个边界框和一个边界球体,那么球体类和盒子类都应该实现

  • isCollidingWith(BoundingBox)
  • isCollidingWith(BoundingSphere)

如果我随后创建一个新的 BoundingVolume,如 BoundingCylinder(通过从基类派生),我希望编译器抛出错误,直到 BoundingBox 和 BoundingSphere 为新的 Cylinder 类型实现了 isCollidingWith 函数(和 ofc 直到 CylinderBoxSphereCylinder 实现了 isCollidingWith

我不确定如何实现这一点,但我考虑过使用 CRTP。 这甚至可能吗?

【问题讨论】:

  • 您所要做的就是将一个纯虚函数(即virtual bool isCollidingWith(BoundingCylinder) = 0;)放入您的基类中,并且在所有派生类都添加实现之前,您会得到一个编译器错误。
  • 这是不可能自动完成的(与@TonyDelroy 的手动答案不同),因为编译器不会跟踪从BoundingVolume 派生的所有类型,因此它无法知道这一点。但是,如果您的所有课程都是凸的,我认为没有它就很容易解决;不过,我需要更仔细地检查才能确定。
  • 添加纯虚函数,看看重新编译时会发生什么。 如果有问题那么询问那个问题。此外,您可能还想了解“双重调度”和“访问者模式”等内容。
  • 搜索“双重调度”解决了我的问题,就像 n.m.说,谢谢! :)

标签: c++ inheritance derived-class pure-virtual


【解决方案1】:

用CRTP可以炮制出这样的东西

class BoundingBox;
class BoundingSphere;

class Shape
{
    public:
        virtual bool isIntersecting(const BoundingBox&) const = 0;
        virtual bool isIntersecting(const BoundingSphere&) const = 0;
};

class BoundingVolumeBase
{
    public:
        virtual bool checkIntersection(const Shape&) const = 0;
        virtual ~BoundingVolumeBase();
};

template<class Derived>
class BoundingVolume : public BoundingVolumeBase
{
        bool checkIntersection(const Shape& shape) const override
        {
            return shape.isIntersecting (static_cast<const Derived&>(*this));
        }
};

class BoundingBox : public BoundingVolume<BoundingBox> {
    // ...
};

class BoundingSphere : public BoundingVolume<BoundingSphere> {
    // ...
};

现在如果我们发明一种新的BoundingVolume,它不会编译,直到向Shape 添加一个新函数。

class BoundingCylinder : public BoundingVolume<BoundingCylinder> {
    // ...
};

BoundingCylinder bc; // <-- this will not compile

没有必要这样做。任何使用虚函数作为唯一类型的基于类型的调度的方法都可以工作(无论如何,你最终可能会得到大致相当于上述的东西)。如果您依赖typeid 或自定义类型标识符,您可能会遇到问题。

这种方法的缺点是类Shape所有具体种类的BoundingVolume相互依赖。

【讨论】:

    【解决方案2】:

    当你在基类中创建纯虚函数,那么派生类的实现是强制,如果派生类没有实现,编译器会给出你一个错误。所以你不必关心是否实现了纯虚函数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-10-14
      • 2015-07-07
      • 2018-01-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多