微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

在子类预期的地方调用传递超类的对象方法

如何解决在子类预期的地方调用传递超类的对象方法

例如我有三个班

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);

编译器引发并出错。

如何在不添加太多逻辑的情况下自动向下转换作为参数给出的对象?

解决方法

编译器不能自动转换对象,你必须手动转换它们,例如:

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);

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。