1

我正在尝试制作一个形状库。有以下类 Shape,具有此声明:

#include "pos.h"
#ifndef SHAPE_H
#define SHAPE_H

class Shape{
protected:
    Pos pos;
public:
    Pos getPos();
    void setPos(Pos pos);
    virtual bool intersection(Shape&);

    Shape():pos((Pos){0,0}){}
    Shape(Pos pos):pos(pos){}
    Shape(int x, int y):pos((Pos){x,y}){}
};

#endif      /*  SHAPE_H */

如您所见,有一个虚函数成员(交集)。此函数旨在计算两个形状是否相交(无论它们是圆形、矩形还是其他形状)。我还声明了这些类(圆形和矩形):

#include "pos.h"
#include "shape.h"

#ifndef RECTANGLE_H
class Rectangle;
#endif      /*  RECTANGLE_H */

#ifndef CIRCLE_H
#define CIRCLE_H

class Circle : public Shape{
private:
    int radius;
public:
    int getRadius(){return radius;}
    void setRadius(int radius){this->radius=radius;}

    bool containsPos(Pos p);
    bool intersection(Circle& c);
    bool intersection(Rectangle& r);

    Circle();
    Circle(Pos pos);
    Circle(int radius);
    Circle(Pos pos, int radius);
};

#endif      /*  CIRCLE_H    */

#include "pos.h"
#include "shape.h"

#ifndef CIRCLE_H
class Circle;
#endif      /*  CIRCLE_H */

#ifndef RECTANGLE_H
#define RECTANGLE_H

class Rectangle : public Shape{
private:
    int width;
    int height;
public:
    int getWidth(){return width;}
    int getHeight(){return height;}

    void setWidth(int width){this->width=width;}
    void setHeight(int height){this->height=height;}

    bool containsPos(Pos pos);
    bool intersection(Rectangle& r);
    bool intersection(Circle& c);

    Rectangle():Shape(),width(0),height(0){}
    Rectangle(int w, int h):Shape(),width(w),height(h){}
    Rectangle(Pos p, int w, int h):Shape(p), width(w),height(h){}
    Rectangle(int x, int y, int w, int h):Shape(x,y), width(w), height(h){}

};

#endif      /*  RECTANGLE_H */

如您所见,我在每个 Shape 子类中为 Shape 的每个其他子类创建了一个成员函数。
看起来不错,但是有问题。当您调用交集给出形状时(我的意思是编译器不知道它的形状,例如从形状向量中获取时)作为参数它不起作用(g ++:没有匹配的调用函数)。
我想这是因为我没有覆盖 Shape 的虚函数,因为只要参数不同,功能就不同(我认为)。
好吧,我想知道是否有一种很酷的方法可以实现这个目标。

编辑:我在现代 c++ 设计的第 11 章中找到了更多关于我的问题的内容。它是关于多方法(带有必须在运行时检查其类型的参数的方法)。在本章的第 9 节中,作者提到当与 static_cast 结合使用时,dynamic_cast 是一个不错的选择。如果我找到更多关于此的信息,我将再次编辑。
编辑 2:在“现代 c++ 设计”的第 11 章中,您可以在第二节中找到作者提到游戏中不同形状之间的碰撞检测是需要使用多方法的典型问题。我没有说,但这个小图书馆是为了游戏而设计的,所以这正是我想要的。

4

2 回答 2

2

设计是错误的。First Shape 需要一个名为的虚拟方法BoundingRect,该方法返回派生类填充区域的 Top、Left、Bottom、Right。那么 Shape.intersection 做的第一件事就是判断边界矩形是否相交;一个微不足道的练习。

现在变得更难了。每个形状都必须提供一个虚拟名称,它返回真实描述该区域Paths的线段/贝塞尔曲线的列表/数组。然后该方法确定任一形状中的任何路径是否相交。intersection

祝你好运。

于 2013-01-27T03:46:27.320 回答
1

启用运行时类型信息,创建一个实际采用 Shape 类的交集方法,并使用 dynamic_cast 找出你得到的对象,然后在派生对象上调用重载的交集调用。

请注意,尽管 RTTI 会严重减慢您的代码速度,并且为每种类型的形状提供特殊功能会严重阻碍代码的灵活性和可维护性。从长远来看,像 Richard 提出的通用解决方案可能更有益。

于 2013-01-28T07:25:10.080 回答