0

我正在编写一些代码来检测不同形状之间的碰撞RectShape,, CircShape,LineShape都继承自一个基类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)接受两个参数的函数,然后通过许多if 语句来比较typeid(shp1)我所有typeid(shp2)typeid派生类。它又脏又乱,但当时我没有任何其他想法。现在我想清理它。添加一种新的形状非常烦人且耗时。

我现在的新想法是简单地TestCollision使用适合不同参数类型的参数进行重载,但是我必须将TestCollision(CircShape&, RectShape&)andTestCollision(RectShape&, CircShape&)作为两个单独的重载,这是不可维护的。另一种思路是自己在派生类内部实现函数,但还是会导致代码重复,更难维护。

我将如何解决这个问题?

4

1 回答 1

1

一个解决方案是使用回调。例如

#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
于 2021-02-06T20:01:31.223 回答