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

C++多项式(Polynomial)与有理数(Rational)类拷贝构造函数实现问题求助

解决Rational类构造函数的拷贝问题及Polynomial类的核心错误

看起来你遇到的核心问题是Polynomial类缺少正确的深拷贝机制,再加上几个语法和设计上的错误,导致Rational对象无法正确保存分子和分母的多项式数据。咱们一步步拆解问题并修复:

一、先解决最致命的语法和设计错误

1. 移除函数参数中的static关键字

C++里不能在函数参数前加static,这是语法错误。你的Polynomial构造函数声明里的static int deg完全不合法,必须去掉static:

// 错误写法
Polynomial(double * var = NULL, static int deg = NULL);
Polynomial(static int deg );

// 修正后
Polynomial(double* var = nullptr, int deg = 0);
Polynomial(int deg);

2. 把Polynomial的static int degree改成非静态成员

static成员是所有类对象共享的,这意味着你所有的Polynomial对象都会共用同一个degree值,完全不符合多项式的设计——每个多项式应该有自己的次数。所以要去掉static:

class Polynomial {
private:
    double* variables; // 注:原拼写varibles改为variables更规范
    int degree; // 去掉static!
    // ... 其他成员
};

二、修复拷贝问题:添加拷贝构造函数和赋值运算符

你的Rational构造函数里用this->numerator = p1;时,因为Polynomial没有自定义拷贝构造函数和赋值运算符,编译器会生成默认的浅拷贝版本。默认浅拷贝只会拷贝指针地址,而不是指针指向的数组内容,这会导致:

  • 多个Polynomial对象共享同一块内存,修改其中一个会影响其他对象
  • 析构时重复释放同一块内存导致崩溃

所以必须为Polynomial添加拷贝构造函数和赋值运算符重载:

// 拷贝构造函数
Polynomial::Polynomial(const Polynomial& other) {
    degree = other.degree;
    // 分配新内存并拷贝数据
    variables = new double[degree];
    for (int i = 0; i < degree; ++i) {
        variables[i] = other.variables[i];
    }
}

// 赋值运算符重载(遵循RAII原则)
Polynomial& Polynomial::operator=(const Polynomial& other) {
    if (this != &other) { // 防止自赋值
        // 先释放当前对象的内存
        delete[] variables;
        // 拷贝新数据
        degree = other.degree;
        variables = new double[degree];
        for (int i = 0; i < degree; ++i) {
            variables[i] = other.variables[i];
        }
    }
    return *this;
}

同时别忘了添加析构函数,避免内存泄漏:

Polynomial::~Polynomial() {
    delete[] variables;
}

三、修复其他逻辑错误

1. 修正构造函数中的数组大小判断

你原来的构造函数里if (deg < (sizeof(var) / sizeof(double)))完全错误,因为var是指针,sizeof(var)得到的是指针的大小(比如64位系统是8字节),不是数组的实际大小。改成直接根据传入的deg分配内存:

Polynomial::Polynomial(double* var, int deg) : degree(deg) {
    variables = new double[degree];
    if (var != nullptr) {
        // 拷贝传入的数组内容
        for (int i = 0; i < degree; ++i) {
            variables[i] = var[i];
        }
    } else {
        // 如果var为空,初始化全0
        memset(variables, 0, degree * sizeof(double));
    }
}

Polynomial::Polynomial(int deg) : degree(deg) {
    variables = new double[deg];
    memset(variables, 0, deg * sizeof(double));
}

2. 修复setCoeff函数的无效操作

你的setCoeff里Polynomial(index);是创建了一个临时对象,不会修改当前对象的任何成员。正确逻辑是如果当前degree小于index,重新分配内存:

void Polynomial::setCoeff(int index, double num) {
    if (index >= degree) {
        // 重新分配更大的内存,拷贝原有数据
        double* newVars = new double[index + 1];
        memset(newVars, 0, (index + 1) * sizeof(double));
        for (int i = 0; i < degree; ++i) {
            newVars[i] = variables[i];
        }
        delete[] variables;
        variables = newVars;
        degree = index + 1;
    }
    variables[index] = num;
}

3. 给Rational类添加print成员函数

你的测试代码里调用了r1.print()和r2.print(),但Rational类没有这个函数,需要补充:

class Rational {
private:
    Polynomial numerator;
    Polynomial denominator;
public:
    Rational(const Polynomial& p1, const Polynomial& p2);
    // 默认构造函数(适配测试代码里的Rational r1;)
    Rational() : numerator(0), denominator(1) {}
    void print() const {
        cout << "Rational: " << endl;
        cout << "Numerator: ";
        numerator.print();
        cout << "Denominator: ";
        denominator.print();
        cout << "-------------------------" << endl;
    }
};

4. 修正Polynomial的print函数逻辑

原来的print函数里size = this->degree;然后while (this->variables[size] == 0)会导致数组越界(数组下标范围是0到degree-1),修正后:

void Polynomial::print() const {
    if (degree == 0 || (degree == 1 && variables[0] == 0)) {
        cout << "0";
        return;
    }

    bool firstTerm = true;
    for (int i = degree - 1; i >= 0; --i) {
        if (variables[i] == 0) continue;

        if (!firstTerm) {
            cout << (variables[i] > 0 ? " + " : " - ");
        } else {
            firstTerm = false;
            if (variables[i] < 0) cout << "-";
        }

        double absVal = abs(variables[i]);
        if (absVal != 1 || i == 0) {
            cout << absVal;
        }
        if (i > 0) {
            cout << "X";
            if (i > 1) {
                cout << "^" << i;
            }
        }
    }
    cout << endl;
}

四、修正后的测试代码

现在你的testRational函数可以正常工作,注意数组元素个数和degree的对应关系(比如6个元素对应degree=6,覆盖X0到X5):

void testRational() {
    Rational r1;
    r1.print();

    double c[] = {0, 2, 2, 3, 4, 5};
    Polynomial p1(c, 6); // 数组有6个元素,degree设为6
    cout << "p1: ";
    p1.print();

    c[0] = 1.2;
    Polynomial p2(c, 3); // 数组前3个元素,degree设为3
    cout << "p2: ";
    p2.print();

    Rational r2(p1, p2);
    cout << "\ntest8" << endl;
    r2.print();
}

总结

核心问题是缺少深拷贝机制,加上static成员和语法错误导致数据没有正确保存。修复这些问题后,Rational对象就能正确存储并打印分子和分母的多项式了。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 18:32:44