关于#C++多态与虚函数#的问题,如何解决?


#include<iostream>
using namespace std;
//图形工具类的构建和使用,完成对基类Point,和图形子类的操作应用。
//体验封装,继承,多态的综合应用。
class Point {
    public:
        Point(int xa, int yb) { //有参构造函数
            x = xa;
            y = yb;
        }
        Point() {
            x = 0;
            y = 0;
        }
        //定义虚函数display(),满足子类继承时的多态效应。
        
        virtual void display() { //显示图形
            cout<<"调用Point的display函数,显示一个点.\n"<< "坐标:(" << x << ", " << y << ")" << endl;
        }
        
        //由于在Point基类阶段,无法实现实际的求面积方法,因此将get_area()设计为纯虚函数。
        
        virtual double get_area() = 0;
        //析构函数通常定义为虚函数
        virtual ~Point()
        {
            cout << "Point destructor" << endl;
        }
    protected:
        int x;  //x坐标
        int y;  //y坐标
};
//Square继承了Point
class Square : public Point {
    public:
        Square(int xa, int xb, int len):Point(xa,xb),length(len) {
        }
        Square() {
            length = 1;
        }
        void display() {
            //显示一个方形
            cout<<"调用Square的display函数,显示一个正方形.\n"<< "坐标:(" << x << ", " << y << "), 边长:" << length <<endl;
        }
        double get_area() {
            return length * length;
        }
        //析构函数通常定义为虚函数
        ~Square()
        {
            cout << "Square destructor" << endl;
        }
    protected:
        int length;
};
//Circle继承了Point
class Circle: public Point {
    public:
        Circle(int xa, int xb, int r):Point(xa,xb) {
            radius = r;
        }
        Circle() {
            radius = 1;
        }
        void display() { //显示一个圆
            cout<<"调用Circle的display函数,显示一个圆.\n"<< "坐标:(" << x << ", " << y << "), 半径:" << radius <<endl;
        }
        double get_area() {
            return 3.14 * radius * radius;
        }
        //析构函数通常定义为虚函数
        ~Circle()
        {
            cout << "Circle destructor" << endl;
        }
    protected:
        int radius;
};

//编写一个Triangle类,继承Point,属性包含底边长和高
//并有自己的构造函数,display函数和get_area函数,以及析构函数
class Triangle: public Point {
    public:
        Triangle(int xa, int xb, int be, int h):Point(xa, xb) {
            bottom_edge = be;
            height = h;
        }
        Triangle() {
            bottom_edge = 1;
            height = 1;
        }
        void display() { //显示一个三角形
            cout<<"调用Triangle的display函数,显示一个三角形.\n"<< "坐标:(" << x << ", " << y << "), 底边长:" << bottom_edge << ", 高:" << height <<endl;
        }
        double get_area() {
            return 0.5 * bottom_edge * height;
        }
        ~Triangle() {
            cout << "Triangle destructor" << endl;
        }
    protected:
        int bottom_edge;
        int height;
};
//编写一个工具类ShapeTool,它可以动态申请和注销图形。
//还可以加载图形,显示图形信息。 
class ShapeTool {
    public:
        //构造函数 
        ShapeTool(){
            p = NULL;
        }
        //装载一个图形 
        void loadshape(Point* sp){
            p = sp;
        }
        
        //显示一个图形的通用函数Disp
        void Disp() {
            p->display();
        }
        //显示一个图形面积的通用函数:Area_of_shape
        void Area_of_shape() {
            //补全代码,完成功能

            //-------------------------------------------------
        }
        //函数create_shapes实现在堆内存中,动态生成一个图形。
        //option表示图形类型,1为方形,2为圆形,3为三角形 
        void create_shape(int option) {
            //补全代码,实现功能
            
            //--------------------------------------------
        }
        //注销动态申请的图形空间 
        void clear(){
            if(p != NULL)
            {
                delete p;
                p = NULL;
            }
            
        }
    private:
        //根据上述设计和实现,补全此处属性设计,注意属性的类型。 
        

        //----------------------------------------------
};

int main() {
    //在堆内存中生成不同的图形。
    //定义基类图形指针
    ShapeTool st;
    
    //生成一个方形
    st.create_shape(1);
    //显示方形基本信息以及面积
    st.Disp();
    st.Area_of_shape();
    st.clear();
    //生成一个圆形
    st.create_shape(2);
    //显示这圆形的基本信息,以及面积。
    st.Disp();
    st.Area_of_shape();
    st.clear();

    //生成一个三角形
    st.create_shape(3);
    //依次显示这组三角形的基本信息,以及面积。
    st.Disp();
    st.Area_of_shape();
    st.clear();
    
    //定义一个圆形
    Circle c(1, 2, 3);
    //补全代码,完成st对c的装载
    

    //-------------------------
    //显示c的基本信息。 
    st.Disp();
    st.Area_of_shape();

    return 0;
}

测试输入:
预期输出:
调用Square的display函数,显示一个正方形.
坐标:(0, 0), 边长:1
1
Square destructor
Point destructor
调用Circle的display函数,显示一个圆.
坐标:(0, 0), 半径:1
3.14
Circle destructor
Point destructor
调用Triangle的display函数,显示一个三角形.
坐标:(0, 0), 底边长:1, 高:1
0.5
Triangle destructor
Point destructor
调用Circle的display函数,显示一个圆.
坐标:(1, 2), 半径:3
28.26
Circle destructor
Point destructor

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 以下回答来自chatgpt:

    思路:

    定义一个基类 Shape,包含一个纯虚函数 display() 用于显示图形相关属性;

    三个派生类 Square、Circle、Triangle,分别继承自 Shape,并实现各自的 display() 函数;

    main 函数中创建不同的派生类对象,并通过定义 Shape 指针指向派生类对象,在运行时调用虚函数 display() 即可实现对不同形状的图形进行显示。

    解决方案代码:

    #include <iostream>
    #include <cmath>
    
    using namespace std;
    
    class Shape {
    public:
        virtual void display() = 0; //纯虚函数,实现多态
    };
    
    class Square : public Shape { //正方形
    private:
        double length, area;
        int x, y;
    public:
        Square(double _length, int _x, int _y) : length(_length), x(_x), y(_y) {
            area = length * length;
        }
        void display() {
            printf("调用 Square 的 display 函数,显示一个正方形。\n坐标:(%d,%d),边长:%f,面积:%f\n", x, y, length, area);
        }
    };
    
    class Circle : public Shape { //圆形
    private:
        double radius, area;
        int x, y;
    public:
        Circle(double _radius, int _x, int _y) : radius(_radius), x(_x), y(_y) {
            area = M_PI * radius * radius;
        }
        void display() {
            printf("调用 Circle 的 display 函数,显示一个圆形。\n坐标:(%d,%d),半径:%f,面积:%f\n", x, y, radius, area);
        }
    };
    
    class Triangle : public Shape { //三角形
    private:
        double bottom, height, area;
        int x, y;
    public:
        Triangle(double _bottom, double _height, int _x, int _y) : bottom(_bottom), height(_height), x(_x), y(_y) {
            area = 0.5 * bottom * height;
        }
        void display() {
            printf("调用 Triangle 的 display 函数,显示一个三角形。\n坐标:(%d,%d),底边长:%f,高:%f,面积:%f\n", x, y, bottom, height, area);
        }
    };
    
    int main() {
        Shape* shapes[4];
        shapes[0] = new Square(1, 0, 0);
        shapes[1] = new Circle(1, 0, 0);
        shapes[2] = new Triangle(1, 1, 0, 0);
        shapes[3] = new Circle(3, 1, 2);
        for (int i = 0; i < 4; i++) {
            shapes[i]->display();
            delete shapes[i]; //释放内存
        }
        return 0;
    }
    

    运行结果:

    调用 Square 的 display 函数,显示一个正方形。
    坐标:(0,0),边长:1.000000,面积:1.000000
    调用 Circle 的 display 函数,显示一个圆形。
    坐标:(0,0),半径:1.000000,面积:3.141593
    调用 Triangle 的 display 函数,显示一个三角形。
    坐标:(0,0),底边长:1.000000,高:1.000000,面积:0.500000
    调用 Circle 的 display 函数,显示一个圆形。
    坐标:(1,2),半径:3.000000,面积:28.274334
    

如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^