标题很烂,我知道。
这里的问题是我有一个从形状类继承的2D和3D形状类

class Shape {
    public:
    virtual double area() = 0;//Calculates the area of some kind of shape
    ~Shape() { delete this; }
};

class Shape2D :public Shape {
public:
    virtual double perimeter() = 0;//Calculates the perimeter of some kind of 2D-shape
    ~Shape2D() {};
};

class Shape3D :public Shape {
public:
    virtual double volume() = 0;//Calculates the volume of some kind of 3D-shape, area function will return surface area
    ~Shape3D() {};
};


决定所有形状默认都有一个区域。在2D形状中,它将具有虚拟周边方法以及Shape的面积。在3D形状中,它将具有体积,而虚拟面积方法将被视为表面积。

我使用的方法是在可以选择2d或3d形状的菜单中:在2d菜单中,我启动:

Shape2D * s = nullptr;


在3d菜单中,我将启动:

Shape3D * s = nullptr;


然后显示任何信息,我使用以下方法:

void displayShape2D(Shape2D *)




void displayShape3D(Shape3D *)


但是,我要执行的方法是声明:

Shape *s = nullputr;


在main的开头,然后以用户选择的任何形状,我都可以设置:

s= new Triangle()


要么

s = new cube();


初始化有效,但是当我尝试制作显示方法时,这就是我遇到的问题。我希望能够做到:

displayShape(Shape *s)


当给定二维形状并在方法内时,我尝试:

cout <<s->perimeter();


会说外围成员不在shape类之内。
然后,问题是试图确定形状是2d还是3d,然后显示2d的面积和周长或3d的表面积和体积。这是可能的吗?还是在专用菜单中创建形状类型,然后使用专用显示方法是唯一的出路?

最佳答案

您要执行的是运行时类型分派。一种方法是使用RTTI。这使您可以执行以下操作:

Shape *s = ...;

if(Shape3D *s3d = dynamic_cast<Shape3D*>(s)) {
    // s3d is now a pointer to a 3d shape
} else if(Shape2D *s2d = dynamic_cast<Shape2D*>(s)) {
    // s2d is now a pointer to a 2d shape
} else {
    // s is neither a Shape2D or Shape3D
}


之所以有效,是因为如果无法将s强制转换为Type *,则dynamic_cast的评估结果为nullptr。因此,如果s可以强制转换为指定的类型,则if语句条件仅求值为true。

关于c++ - 当使用形状参数时,如何灵活处理2D和3D形状的方法参数,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35821864/

10-11 23:06
查看更多