如果我从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()。”
EDIT 根据下面的响应,我尝试将basePtr对象dynamic_cast成CCircle,如下所示:
CCircle *circle = new CCircle(1, 2, 3.3);
basePtr = dynamic_cast<CCircle *>(circle);
然而,这也失败了。我从来没有做过dynamic_cast,也不熟悉C ++中的大部分语法,所以非常感谢任何帮助。
答案 0 :(得分:4)
你可能会对演员阵容小心。首先,dynamic_cast
添加运行时开销以检查指针的类型(请参阅 rtti )。 static_cast
更便宜但不检查对象的动态类型。
向下倾斜是可能(!)在您的设计中出现问题的指标。绝不是这种情况,尤其是如果你正在学习C ++ OOP试着避免它们。
由于向getRadius
添加CShape
没有意义(因为并非所有形状都有半径),处理CShape*
的函数不应依赖于对象是CCircle
。
例如,您可能正在尝试确定形状的区域。对于所有形状而言,这可能是一件有意义的事情,因此您需要添加一个virtual
抽象函数来计算形状的面积。然后你的圆圈将通过使用它的半径来实现它,使用它的边长的乘积来实现矩形等等。
编辑:了解原因
CShape *basePtr = new CCircle(1, 2, 3.3);
basePtr->getRadius();
无法工作,你必须明白C ++是强类型的。在第二行中,您尝试从getRadius
访问名为CShape
的成员。该类(或其任何父类)没有这样的成员。确实(在程序运行时)变量basePtr
指向类型为CCircle
的对象,但在编译时无法知道(在一般情况下,即)。因此,C ++甚至懒得检查派生类型,因为(再次,一般而言)它根本不能。在编译这一行时,它甚至可能知道所有派生类型,因此它没有机会理解你的意图。
就编译器而言,basePtr
可能指向一个不具有getRadius
成员的类型的对象。
答案 1 :(得分:2)
要获得getRadius
功能,您必须声明类型CCircle
:
CCircle *basePtr = new CCircle(1, 2, 3.3);
basePtr->getRadius();
否则,如果您要将basePtr
声明为CShape
,请使用动态绑定dynamic_cast
或直接使用c-style强制转换,如@Janisz所指出的那样。
CShape *basePtr = new CCircle(1, 2, 3.3);
CCircle *child
// choose one of the two ways, either this:
child = (CCircle*)basePtr; // C-style cast
// or this:
child = dynamic_cast<CCircle*>(basePtr); // C++ version
child->getRadius();
答案 2 :(得分:0)
你可以从CShape到Circle
进行静态演员(http://www.cplusplus.com/doc/tutorial/typecasting/)或者,您可以将getRadius()声明为CShape中的虚函数,在给定类的名称时您可能不想这样做。