gpt4 book ai didi

c++ - 使基类指针表现得像 C++ 中的派生类

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:38:19 25 4
gpt4 key购买 nike

如果我从我的 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/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com