如果我从我的 Shape 基类创建一个指针,我如何才能让它表现得像圆(派生)类?这是我的类定义:
//CShape.h class definition
//Shape class definition
#ifndef CSHAPE_H
#define CSHAPE_H
class CShape
{
protected:
float area;
virtual void calcArea();
public:
float getArea()
{
return area;
}
};
class CCircle : public CShape
{
protected:
int centerX;
int centerY;
float radius;
void calcArea()
{
area = float(M_PI * (radius * radius));
}
public:
CCircle(int pCenterX, int pCenterY, float pRadius)
{
centerX = pCenterX;
centerY = pCenterY;
radius = pRadius;
}
float getRadius()
{
return radius;
}
};
在我调用这些对象的项目文件中,我有以下代码:
CShape *basePtr = new CCircle(1, 2, 3.3);
basePtr->getRadius();
在我看来这应该可行,但是我被告知 CShape 没有成员“getRadius()”。
编辑 根据下面的响应,我尝试将 basePtr 对象 dynamic_cast 为 CCircle,如下所示:
CCircle *circle = new CCircle(1, 2, 3.3);
basePtr = dynamic_cast<CCircle *>(circle);
然而,这也失败了。我从未做过 dynamic_cast 并且不熟悉 C++ 中的大部分语法,因此非常感谢任何帮助。
最佳答案
您可能要小心转换。首先,dynamic_cast
添加了运行时开销以检查指针的类型(参见 rtti)。 static_cast
便宜很多但不检查对象的动态类型。
向下转型表明您的设计可能 (!) 有问题。情况并非总是如此,但特别是如果您正在学习 C++ OOP,请尽量避免使用它们。
由于将 getRadius
添加到 CShape
没有意义(只是因为并非所有形状都有半径),因此处理 CShape* 的函数
不应依赖对象是 CCircle
。
例如,您可以尝试确定形状的面积。这可能对所有形状都有意义,因此您可以添加一个 virtual
抽象函数来计算形状的面积。然后你的圆将通过使用它的半径来实现它,一个矩形通过使用它的边长的乘积等等。
编辑:理解原因
CShape *basePtr = new CCircle(1, 2, 3.3);
basePtr->getRadius();
不行,你得明白C++是强类型的。在第二行中,您试图从 CShape
访问一个名为 getRadius
的成员。该类(及其任何父类)没有这样的成员。确实(当您的程序运行时)变量 basePtr
指向类型为 CCircle
的对象,但在编译时无法知道(在一般情况下,是)。因此,C++ 甚至懒得去检查派生类型,因为(同样,通常)它根本做不到。编译这一行时,它甚至可能知道所有派生类型,因此它没有机会理解您的意图。
就编译器而言,basePtr
可能指向一个不没有getRadius
类型的对象成员(member)。
关于c++ - 使基类指针表现得像 C++ 中的派生类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11812283/