c ++纯虚函数依赖于派生类
c++ Pure virtual functions dependent on derived classes
我正在研究边界 box/collision 检测系统,我正在使用不同类型的边界体积,id 就像所有边界体积一样导出相同的基础 class 然后使用纯虚函数强制所有派生的 classes 实现
等基本功能
isCollidingWith(BoudingBox)
但这就是给我带来麻烦的原因:我不希望他们为每个 BoudingVolume
类型实现一个函数。所以如果我有一个边界框和一个边界球体,那么球体 class 和盒子 class 都应该实现
isCollidingWith(BoundingBox)
isCollidingWith(BoundingSphere)
如果我然后创建一个新的 BoundingVolume,如 BoundingCylinder
(通过从基础 class 派生),我希望编译器抛出一个错误,直到 BoundingBox 和 BoundingSphere 实现了 isCollidingWith
函数用于新的 Cylinder
类型(并且直到 Cylinder
为 Box
、Sphere
和 Cylinder
实现了 isCollidingWith
。
我不确定如何着手实现它,但我考虑过使用 CRTP。
这可能吗?
当你在基础 class 中创建 纯虚函数 时,对于派生 class 是 强制性的 对于它的实现,如果 derived class 没有实现它,那么编译器会给你一个 error。所以你不必关心是否实现了纯虚函数。
可以用 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
或自定义类型标识符,您可能会遇到问题。
这种方法的缺点是 class Shape
和 all 具体类型 BoundingVolume
.
的相互依赖
我正在研究边界 box/collision 检测系统,我正在使用不同类型的边界体积,id 就像所有边界体积一样导出相同的基础 class 然后使用纯虚函数强制所有派生的 classes 实现
等基本功能isCollidingWith(BoudingBox)
但这就是给我带来麻烦的原因:我不希望他们为每个 BoudingVolume
类型实现一个函数。所以如果我有一个边界框和一个边界球体,那么球体 class 和盒子 class 都应该实现
isCollidingWith(BoundingBox)
isCollidingWith(BoundingSphere)
如果我然后创建一个新的 BoundingVolume,如 BoundingCylinder
(通过从基础 class 派生),我希望编译器抛出一个错误,直到 BoundingBox 和 BoundingSphere 实现了 isCollidingWith
函数用于新的 Cylinder
类型(并且直到 Cylinder
为 Box
、Sphere
和 Cylinder
实现了 isCollidingWith
。
我不确定如何着手实现它,但我考虑过使用 CRTP。 这可能吗?
当你在基础 class 中创建 纯虚函数 时,对于派生 class 是 强制性的 对于它的实现,如果 derived class 没有实现它,那么编译器会给你一个 error。所以你不必关心是否实现了纯虚函数。
可以用 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
或自定义类型标识符,您可能会遇到问题。
这种方法的缺点是 class Shape
和 all 具体类型 BoundingVolume
.