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

标签 c++ inheritance pointers

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

相关文章:

C++ vector<vector<double>> 加倍 **

c++ - Boost.Intrusive Containers - 不同大小的元素

C++ - 修改文件而不创建新文件

c++ - 从基类发送和接收序列化类

swift - 继承类中的类 func() 存在奇怪的歧义 [Swift]

javascript - CoffeeScript 类

c++ - 可以比较两个指向成员函数的指针是否相等吗?

inheritance - 打印为我提供了类列表上的内存地址,而不是特定的 STR

c - C 中函数的两个或多个值

c - malloc 总是分配相同的地址