标题很烂,我知道。
这里的问题是我有一个从形状类继承的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/