为不同类型的参数实现不同的方法

Implementing a different method for different types of arguments

我正在编写一些代码来检测不同形状之间的碰撞,RectShapeCircShapeLineShape 都继承自基础 class Shape。我目前的实施工作非常糟糕。首先,我定义了一堆特定于案例的函数:

bool LineLineCollision(LineShape& line1, LineShape& line2) {
    // do some math
}

bool CircRectCollision(CircShape& circ, RectShape& rect) {
    // some more math
}

// and so on for all cases

显然所有这些在任何实施中都是必需的。问题出在函数 bool TestCollision(Shape& shp1, Shape& shp2) 中,它接受两个参数,然后通过 many if 语句将 typeid(shp1)typeid(shp2)typeid 我所有派生的 classes。它又脏又乱,但当时我没有任何其他想法。现在我想清理它。添加一种新的形状是难以想象的烦人和耗时。

我现在的新想法是简单地用适合不同参数类型的参数重载 TestCollision,但是我必须将 TestCollision(CircShape&, RectShape&)TestCollision(RectShape&, CircShape&) 作为两个单独的重载,这就是不可维护。另一个想法是在派生的 classes 本身内部实现函数,但它仍然会导致代码重复并且更难维护。

我该如何解决这个问题?

A​​ 解决方案是使用回调。例如

#include <iostream>

struct Line;
struct Circ;

struct Shape {
    virtual void Collision(Line*) = 0;
    virtual void Collision(Circ*) = 0;
    virtual void Collision(Shape*) = 0;
};

class Line : public Shape {
private:
    void Collision(Line*) override {
        std::cout << "Line-Line\n";
    }
    void Collision(Circ*) override {
        std::cout << "Circ-Line\n";
    }
public:
    void Collision(Shape* other) override {
        other->Collision(this);
    }
};

class Circ : public Shape {
private:
    void Collision(Line*) override {
        std::cout << "Line-Circ\n";
    }
    void Collision(Circ*) override {
        std::cout << "Circ-Circ\n";
    }
public:
    void Collision(Shape* other) override {
        other->Collision(this);
    }
};

#include<memory>

int main(){
    std::unique_ptr<Shape> obj1 = std::make_unique<Line>();
    std::unique_ptr<Shape> obj2 = std::make_unique<Circ>();
    std::unique_ptr<Shape> obj3 = std::make_unique<Line>();

    obj1->Collision(obj2.get());
    obj1->Collision(obj3.get());

}

输出:

Line-Circ
Line-Line