【问题标题】:How to access member functions of a derived class through a base pointer?如何通过基指针访问派生类的成员函数?
【发布时间】:2021-08-05 14:50:48
【问题描述】:
#include <iostream>
#include <string>
using namespace std;

class Shape {
    private:
        string name;
    public:
        Shape(){name = "Shape";}
        Shape(string n){name = n;}
        void setName(string n){name = n;}
        string getName(){return name;}
        double calcarea(){return 0;}
};

class Square : public Shape {
    private:
        double side;
    public:
    Square(){side = 1; Shape("Square");}
    Square(double s){side = s; Shape("Square");}
    void setSide(double s){side = s;}
    double getSide(){return side;}
    double calcarea(){double area = side * side; return area;}
};

class Circle : public Shape{
    private:
        double radius;
    public:
        Circle(){radius = 1; Shape("Circle");}
        Circle(double r){radius = r; Shape("Circle");}
        Circle(double ra, string n){radius = ra; setName(n);}
        void setRadius(double r){radius = r;}
        double getRadius(){return radius;}
        double calcarea(){double area = 3.14 * radius * radius; return area;}

};

int main()
{
    Shape* shapepointer[5];
    shapepointer[0] = new Shape;
    shapepointer[1] = new Square;
    shapepointer[2] = new Circle;
    shapepointer[3] = new Circle;
    shapepointer[4] = new Square;

    shapepointer[1]->setSide(3);
    shapepointer[2]->setRadius(2);
    shapepointer[3]->setRadius(7);
    shapepointer[4]->setSide(5);


    return 0;
}

如果我没有正确格式化这篇文章或未能在帖子中做一些让你的生活更轻松的事情,我深表歉意,我是新来的,抱歉模组/阅读本文的人。所以我的任务是:

"创建一个 main() 函数来创建一个名为的基指针数组 shapepointer[] 大小为 5。动态创建/实例化以下形状 这些指针……”

现在一切正常,我创建了类、它们的构造函数、重载构造函数,以及访问器和修改器。但是,现在我已经在 main() 中实例化了一个作为基指针的数组,我得到了错误 no member named 'setSide' in 'Shape'no member named 'setRadius' in '形状'

从我对错误消息的解释来看,Shape 指针似乎属于基类,因此无法访问它尝试使用的派生类的成员函数。我不知道如何解决这个问题,因为任务的指令要求指针是基类指针。我也很困惑,因为如果我解释的是真的,那么使用我使用的基本数组/指针从其他类动态实例化对象怎么没有错误?非常感谢您能帮我解决这个问题,谢谢。

【问题讨论】:

  • 您可以使用dynamic_cast,但您的基类至少需要一个虚函数。不是你问的,但Square(){side = 1; Shape("Square");} 中的Shape("Square"); 并没有按照你的想法做,它创建了一个临时基础对象,该对象立即被销毁。您需要在初始化列表中调用基本构造函数,例如Square() : Shape("Square), side(1) {} 您会注意到我也将side 分配到那里。通常首选初始化而不是在构造函数体中赋值。
  • calcarea 函数在这种情况下绝对应该是虚拟的,因为您希望调用派生类中的覆盖函数。我猜你的作业可能暗示了如何处理基类指针。你可以再读一遍,看看你能不能弄清楚该怎么做。
  • 是的,calcarea 函数最终被认为是虚拟的,但我的任务指令并没有告诉我在动态分配和实例化对象之前将其设为虚拟函数。
  • @Retired Ninja 关于需要在初始化列表中调用基本构造函数,例如 Square() : Shape("Square"),我有这个程序的 2 个版本,我完全按照你提到我应该这样做,它肯定注意到了谢谢。

标签: c++ pointers inheritance polymorphism


【解决方案1】:

我想通了。一位同学帮助了我:

Shape* shapepointer[5];
    
    shapepointer[0] = new Shape();
    shapepointer[1] = new Square(3);
    shapepointer[2] = new Circle(2);
    shapepointer[3] = new Circle(7);
    shapepointer[4] = new Square(5);

简单修复,将动态分配的对象更改为构造函数。 calcarea() 函数也被设置为基类“Shape”中的虚函数。

【讨论】:

    【解决方案2】:

    在我看来,错误的出现是因为 shapepointer 数组中的一个 element 指向“Shape”类对象。 在内存中,shapepointer类对象的指针可以在shape类的成员中访问。 另一方面,shapepointer指针没有setSidesetRadius的任何功能。

    您可以在Shape类中将这些函数定义为虚函数并享受它。

    int main()
    {
        Shape* shapepointer[5];
        shapepointer[0] = new Shape;
        shapepointer[1] = new Square;
        shapepointer[2] = new Circle;
        shapepointer[3] = new Circle;
        shapepointer[4] = new Square;
    
        ((Square*)shapepointer[1])->setSide(3);
        ((Circle*)shapepointer[2])->setRadius(2);
        ((Circle*)shapepointer[3])->setRadius(7);
        ((Square*)shapepointer[4])->setSide(5);
    
    
        return 0;
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-27
      • 2015-02-04
      • 2016-07-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多