我想使用继承来根据层次结构中的位置以不同的方式处理对象
假设您构建了Shape对象的层次结构,如:
class Shape {} ;
class Sphere : public Shape {} ;
class Triangle : public Shape {} ; ...
然后为Ray类配备如下方法:
class Ray
{
Intersection intersects( const Sphere * s ) ;
Intersection intersects( const Triangle * t ) ;
};
存储各种类型的各种Shape *数组并调用
vector<Shape*> shapes ; ...
//foreach shape..
Intersection int = ray.intersects( shapes[ i ] )
但是你得到编译器错误
错误C2664:'交点Ray :: intersects(const Sphere *)const':无法将参数1从'Shape * const'转换为'const Sphere *'
你做错了什么?
使用
进行其他方式是唯一的方法class Shape
{
virtual Intersection intersects( const Ray* ray )=0 ;
} ;
然后每个类覆盖相交?然后调用
//foreach shape..
Intersection int = shapes[i]->intersects( ray ) ;
你能以我展示的第一种方式或从未这样做过吗?
答案 0 :(得分:4)
你必须以相反的方式做到这一点。重载解析在编译时进行,当您调用它的类型为Shape*
时。
答案 1 :(得分:4)
不,你不能以第一种方式去做。 C ++中的重载分辨率基于函数参数的 static 类型。它在编译时解决。在您的示例中,静态类型为Shape *
,并且您的类中没有接受Shape *
的函数(因此错误)。编译器并不关心您的指针在运行时实际上是否指向Sphere
。
要实现您要实现的功能,您必须通过依赖于动态类型的对象的工具“引导”您的调用,即通过虚拟函数调用,这是您在你的第二个例子。
你的第二个例子有点简化,因为所涉及的一个对象的类型在编译时是已知的(Ray
)。在更复杂的情况下,“交叉点”中涉及的两个对象可以是动态类型。如果您愿意处理类似的事情,可以使用所谓的“双重调度”技术(搜索它)。
答案 2 :(得分:0)
可能你可以用RTTI信息来提取它。我没有这样做但可能有可能。
class Ray
{
Intersection intersects( const Sphere * s ) ;
Intersection intersects( const Triangle * t ) ;
Intersection intersects( const Shape * s ) {
//act on RTTI info, or
//use dynamic_cast to other types and check if the result is NULL or not
}
};