调用对象方法传递超类期望子类
Posted
技术标签:
【中文标题】调用对象方法传递超类期望子类【英文标题】:Calling object method passing superclass where subclass expected 【发布时间】:2021-01-12 15:05:24 【问题描述】:例如我有三个班级
class Shape
static bool collide(Box * a, Box * b)
static bool collide(Box * a, Sphere * b)
static bool collide(Sphere * a, Sphere * b)
;
class Box : public Shape;
class Sphere : public Shape;
例如在其他地方我有这段代码
Shape * a = new Box();
Shape * b = new Sphere();
Shape::collide(a, b);
编译器引发错误。
如何在不添加太多逻辑的情况下自动向下转换作为参数给出的对象?
【问题讨论】:
听起来你需要一些polymorphism 【参考方案1】:编译器不能自动转换对象,你必须手动转换它们,例如:
class Box;
class Sphere;
class Shape
virtual ~Shape()
static bool collide(Shape *a, Shape *b);
static bool collide(Box *a, Box *b);
static bool collide(Box *a, Sphere *b);
static bool collide(Sphere *a, Sphere *b);
;
class Box : public Shape;
class Sphere : public Shape;
bool Shape::collide(Shape *a, Shape *b)
if (Box *a_box = dynamic_cast<Box*>(a))
if (Box *b_box = dynamic_cast<Box*>(b))
return collide(a_box, b_box);
if (Sphere *b_sphere = dynamic_cast<Sphere*>(b))
return collide(a_box, b_sphere);
else if (Sphere *a_sphere = dynamic_cast<Sphere*>(a))
if (Sphere *b_sphere = dynamic_cast<Sphere*>(b))
return collide(a_sphere, b_sphere);
return false;
bool Shape::collide(Box *a, Box *b) ...
bool Shape::collide(Box *a, Sphere *b) ...
bool Shape::collide(Sphere *a, Sphere *b) ...
Shape * a = new Box();
Shape * b = new Sphere();
Shape::collide(a, b);
不用说,随着新形状的添加,这会变得有点乏味。您应该改为将单个 virtual
方法添加到 Shape
本身,并让派生类覆盖它以根据需要处理不同的类型,例如:
class Shape
virtual ~Shape()
virtual bool collide(Shape * b) return false; ;
;
class Box : public Shape
bool collide(Shape * b) override
if (Box *b_box = dynamic_cast<Box*>(b))
return ...;
if (Sphere *b_sphere = dynamic_cast<Sphere*>(b))
return ...;
return Shape::collide(b);
;
;
class Sphere : public Shape
bool collide(Shape * b) override
if (Sphere *b_sphere = dynamic_cast<Sphere*>(b))
return ...;
return Shape::collide(b);
;
;
Shape * a = new Box();
Shape * b = new Sphere();
a->collide(b);
【讨论】:
以上是关于调用对象方法传递超类期望子类的主要内容,如果未能解决你的问题,请参考以下文章