You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++虚函数重写计算多图形面积时所有结果返回1的问题

问题描述

使用C++ virtual与override关键字实现多态,计算矩形、菱形、三角形、圆形的面积时,所有图形的面积返回值恒为1;即使在main函数中尝试给矩形传入参数调整面积计算输入,输出仍显示所有图形面积为1,异常输出内容如下:

My figure type is My area is 1 My figure type is Triangle My area is 1 My figure type is Circle My area is 1 My figure type is Rhombus My area is 1

问题原始代码:

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

class Figure
{
protected:
    double x;
    double y;
    string type;
public:
    Figure(double m_x, double m_y) : x{ m_x }, y{ m_y } {};
    virtual double area(double x, double y) { return 0; };
    Figure(double m_x, double m_y, double x = 0, double y = 0) { m_x = x; m_y = y; }
    virtual void Print() const final;
    Figure(const Figure& obj);
    Figure() {};    
};

class Rectangle : public Figure
{
public: 
    Rectangle(double x, double y)
    {
        this->x = x; 
        this->y = y; 
        type = " Rectangle"; 
        double area();
    }

    double area(double x, double y) override {
        return x * y;
    }

    Rectangle() {};
};

class Triangle : public Figure
{
public:
    Triangle(double x, double y)
    {
        this->x = x; 
        this->y = y; 
        type = " Triangle";
        double area();
    }

    double area(double x, double y)override {
        return x * y / 2;
    }

    Triangle() {};
};

class Circle : public Figure
{
public:
    Circle(double x, double y)
    {
        this->x = x; 
        this->y = y; 
        type = " Circle"; 
        double area();
    }

    double area(double x, double y)override {
        return pow(x, 2) * 3.14;
    }

    Circle() {};
};

class Rhombus : public Figure
{
public:
    Rhombus(double x, double y)
    {
        this->x = x; this->y = y; type = " Rhombus"; double area();
    }

    double area(double x, double y)override {
        return x * y / 2;
    }

    Rhombus() {};
};

void Figure::Print() const 
{
    cout << "    My figure type is" << type 
         << "   My area is " << &Figure::area;
}

int main()
{
    Rectangle rectangle;
    rectangle.area(5.4,6.2);
    rectangle.Print();
    Triangle triangle(4.5,5.3);
    triangle.Print();
    Circle circle(6.6, 8.8);
    circle.Print();
    Rhombus rhombus(3.4,5.4);
    rhombus.Print();
}
错误原因

代码存在多处语法和逻辑错误,直接导致输出异常:

  • Print函数中输出面积的写法完全错误:&Figure::area是取基类area成员函数的指针,不是调用多态方法计算面积。C++中输出成员函数指针时会隐式转换为bool类型,非空指针转换结果恒为true,输出时固定显示为1,这是所有面积返回1的直接原因。
  • 基类Figure的构造函数冲突、逻辑错误:同时定义了二参构造、带默认参数的四参构造、无参构造,其中四参构造的赋值方向写反,把形参m_x/m_y赋值给了默认值为0的局部参数x/y,根本没有给类的成员变量赋值;另外声明了拷贝构造函数但没有实现,本身就会触发链接错误。
  • 所有派生类构造函数内写的double area();是无效的函数声明,不是调用成员方法,没有任何实际作用。
  • main中创建矩形对象时调用了无参构造,没有给长宽成员变量赋初始值;单独调用rectangle.area(5.4,6.2)得到的返回值没有被存储或使用,完全不影响Print的输出结果。
  • area接口设计不合理:类内部已经存储了计算所需的x/y成员变量,不需要再给area方法传参,既违背封装逻辑,也容易出现传参错误,例如圆形面积计算只需要半径,原接口强制传两个参数,第二个参数完全无效。
修复后代码

针对以上问题调整后可正常运行的代码如下:

#include <iostream>
#include <string>
#include <cmath>

using namespace std;

class Figure
{
protected:
    double x;
    double y;
    string type;
public:
    // 统一构造逻辑,清理冗余冲突的构造声明
    Figure(double m_x = 0, double m_y = 0, string m_type = "") : x(m_x), y(m_y), type(m_type) {};
    // 无参虚函数,直接读取成员变量计算,支持多态调用
    virtual double area() const { return 0; };
    virtual void Print() const final;
};

class Rectangle : public Figure
{
public: 
    Rectangle(double length, double width) : Figure(length, width, "Rectangle") {}
    double area() const override {
        return x * y;
    }
};

class Triangle : public Figure
{
public:
    Triangle(double base, double height) : Figure(base, height, "Triangle") {}
    double area() const override {
        return x * y / 2;
    }
};

class Circle : public Figure
{
public:
    Circle(double radius) : Figure(radius, 0, "Circle") {}
    double area() const override {
        return pow(x, 2) * 3.1415926;
    }
};

class Rhombus : public Figure
{
public:
    Rhombus(double diag1, double diag2) : Figure(diag1, diag2, "Rhombus") {}
    double area() const override {
        return x * y / 2;
    }
};

void Figure::Print() const 
{
    cout << "    My figure type is " << type 
         << "   My area is " << area() << endl;
}

int main()
{
    // 创建对象时直接传入计算所需参数,不使用无参构造生成未初始化对象
    Rectangle rectangle(5.4,6.2);
    rectangle.Print();
    Triangle triangle(4.5,5.3);
    triangle.Print();
    Circle circle(6.6);
    circle.Print();
    Rhombus rhombus(3.4,5.4);
    rhombus.Print();
    return 0;
}

内容的提问来源于stack exchange,提问作者Larrythelobster

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 09:48:16