JiLin University 面向对象程序设计上机实验第一题实验报告

  • 实验题目

对如下多项式(Polynomial)编写类定义

其中,n为多项式的次数。完成如下功能:

  1. 可存储任意大的多项式(提示:可用动态数组实现)。
  2. 定义构造函数、析构函数、拷贝构造函数。
  3. 包含一个static成员存储定义的多项式数量。
  4. 定义一个成员函数输出多项式。(可参照-x^4-6x^3+5格式输出,注意化简)
  5. 定义一个成员函数计算多项式的值。
  6. 重载“+”运算符,实现两个多项式相加。
  7. 重载“-”运算符,实现两个多项式相减。
  8. 重载“*”运算符,实现两个多项式相乘。
  9. 重载“=”运算符,实现两个多项式的赋值运算。
  10. 在main函数中编写测试代码。

要求:采用多文件实现。考虑:哪些成员函数可以声明为const,

把其中某个运算符重载为友元函数。

  • 解决方案

1.类定义:定义Polynomial类,包含动态数组来存储多项式的项 (系数和指数)。

2.静态成员:定义一个静态成员变量count来跟踪多项式对象的数量。

3.成员函数:

Print:遍历项并输出多项式,注意处理负系数和省略零项。

Evaluate:使用Horner法则或循环遍历项来计算多项式的值。

4.运算符重载:实现加法、减法、乘法和赋值运算符。

5.友元函数:将减法运算符重载为友元函数,因为它需要访问类的私有成员。

6.测试:在main函数中创建多项式对象,测试所有功能。

  • 程序清单

Polynomial.h

#ifndef POLYNOMIAL_H

#define POLYNOMIAL_H

#include <iostream>

#include <vector>

class Polynomial {

private:

    std::vector<int> coeffs; // 系数数组,从最高次到0次

    static int count; // 静态成员变量,记录定义的多项式数量

public:

    // 构造函数

    Polynomial();

    Polynomial(const std::initializer_list<int>& initList);

    // 析构函数

    ~Polynomial();

    // 拷贝构造函数

    Polynomial(const Polynomial& other);

    // 赋值运算符

    Polynomial& operator=(const Polynomial& other);

    // 输出多项式

    void print() const;

    // 计算多项式的值

    int evaluate(int x) const;

    // "+" 运算符重载

    Polynomial operator+(const Polynomial& other) const;

    // "-" 运算符重载

    Polynomial operator-(const Polynomial& other) const;

    // "*" 运算符重载(友元函数)

    friend Polynomial operator*(const Polynomial& lhs, const Polynomial& rhs);

    // 静态成员变量访问器

    static int getCount() { return count; }

};

#endif // POLYNOMIAL_H

Polynomial.cpp

#include "Polynomial.h"

#include <iostream>

#include <algorithm>

// 初始化静态成员变量

int Polynomial::count = 0;

// 构造函数

Polynomial::Polynomial() : coeffs() {

    ++count;

}

Polynomial::Polynomial(const std::initializer_list<int>& initList) : coeffs(initList) {

    ++count;

    // 这里可以添加代码以去除末尾的零

}

// 析构函数

Polynomial::~Polynomial() {

    --count;

}

// 拷贝构造函数

Polynomial::Polynomial(const Polynomial& other) : coeffs(other.coeffs) {

    ++count;

}

// 赋值运算符

Polynomial& Polynomial::operator=(const Polynomial& other) {

    if (this != &other) {

        coeffs = other.coeffs;

    }

    return *this;

}

// 输出多项式

void Polynomial::print() const {

    bool isFirstTerm = true;

    bool isPositive = true;

    for (int i = coeffs.size() -1; i >= 0; --i) {

        if (coeffs[i] != 0) {

            if (!isFirstTerm) {

                std::cout << (isPositive ? " + " : " - ");

            }

            isFirstTerm = false;

            isPositive = coeffs[i] > 0;

            if (i != coeffs.size()) {

                std::cout << std::abs(coeffs[i]) << "x^" << i;

            }

            else {

                std::cout << coeffs[i];

                if(i==0)

                    isFirstTerm = true;

            }

        }

    }

    std::cout << std::endl;

}

// 计算多项式的值

int Polynomial::evaluate(int x) const {

    int result = 0;

    for (size_t i = 0; i < coeffs.size(); ++i) {

        result += coeffs[i] * std::pow(x, i);

    }

    return result;

}

// "+" 运算符重载

Polynomial Polynomial::operator+(const Polynomial& other) const {

    Polynomial result;

    int maxN = std::max(coeffs.size(), other.coeffs.size()) - 1;

    result.coeffs.resize(maxN + 1, 0);

    for (int i = 0; i <= maxN; ++i) {

        result.coeffs[i] = (i < coeffs.size() ? coeffs[i] : 0) +

            (i < other.coeffs.size() ? other.coeffs[i] : 0);

    }

    return result;

}

// "-" 运算符重载

Polynomial Polynomial::operator-(const Polynomial& other) const {

    Polynomial result;

    int maxN = std::max(coeffs.size(), other.coeffs.size()) - 1;

    result.coeffs.resize(maxN + 1, 0);

    for (int i = 0; i <= maxN; ++i) {

        result.coeffs[i] = (i < coeffs.size() ? coeffs[i] : 0) -

            (i < other.coeffs.size() ? other.coeffs[i] : 0);

    }

    return result;

}

// "*" 运算符重载(友元函数)

Polynomial operator*(const Polynomial& lhs, const Polynomial& rhs) {

    Polynomial result;

    int maxN = lhs.coeffs.size() + rhs.coeffs.size() - 2;

    result.coeffs.resize(maxN + 1, 0);

    for (size_t i = 0; i < lhs.coeffs.size(); ++i) {

        for (size_t j = 0; j < rhs.coeffs.size(); ++j) {

            result.coeffs[i + j] += lhs.coeffs[i] * rhs.coeffs[j];

        }

    }

    return result;

}

main.cpp

#include "Polynomial.h"

#include <iostream>

int main() {

    // 测试代码...

    Polynomial p1{ 1, 2, 3,4,5,6 }; // 3x^2 + 2x + 1

    Polynomial p2{ 4, 5, 6 }; // 6x^2 + 5x + 4

    p1.print();

    p2.print();

    std::cout << "Sum: ";

    (p1 + p2).print();

    std::cout << "Difference: ";

    (p1 - p2).print();

    std::cout << "Product: ";

    (p1 * p2).print();

    std::cout << "Polynomial count: " << Polynomial::getCount() << std::endl;

return 0;

}
  • 程序运行结果
  • 体会与总结

(一)知识点理解

我深入理解了C++面向对象编程的概念,包括类定义、构造函数、析构函数、拷贝构造函数、静态成员、运算符重载和友元函数。

1.类定义(Class Definition):

类是面向对象编程的核心。它定义了一个对象的模板或蓝图,描述了对象应有的属性和方法。类定义通常包括数据成员(属性)和成员函数(方法)。

2.构造函数(Constructor):

构造函数是一个特殊的成员函数,用于初始化类的对象。当创建类的对象时,构造函数会被自动调用。构造函数没有返回类型(连void也没有),并且其名称与类名相同。

3.析构函数(Destructor):

析构函数是另一个特殊的成员函数,当类的对象离开其作用域或被显式删除时,析构函数会被自动调用。析构函数用于释放对象可能占用的资源,如动态分配的内存。析构函数的名称是类名前加上波浪线(~),也没有返回类型。

4.拷贝构造函数(Copy Constructor):

拷贝构造函数是一个特殊的构造函数,用于从一个已存在的对象创建一个新的对象,并将其初始化为与已存在对象相同的状态。拷贝构造函数只有一个参数,该参数是对同类对象的引用(通常为const引用),用于从源对象复制数据。

5.静态成员(Static Member):

静态成员属于类本身,而不是类的某个对象。这意味着无论创建多少个类的对象,静态成员都只有一个副本。静态成员可以是数据成员(静态变量)或成员函数(静态方法)。静态成员变量在类外部定义,而静态成员函数可以直接访问类的静态成员和其他非静态成员。

6.运算符重载(Operator Overloading):

运算符重载允许程序员重新定义或重载大部分内置运算符,以便它们可以用于用户自定义的数据类型。例如,可以重载+运算符使其能够用于两个自定义类对象的加法操作。

7.友元函数(Friend Function):

友元函数不是类的成员函数,但它可以访问类的私有和保护成员。友元函数可以是普通函数,也可以是其他类的成员函数。通过在类定义中声明为友元,该函数就获得了访问类私有成员的权限。注意,过度使用友元可能会破坏封装性,因此应谨慎使用。

(二)运行情况分析

在编写和测试代码时,要注意处理边界情况和异常情况,例如零系数项、负系数和多项式相加/相减/相乘后的化简。

(三)调试程序获得的经验与体会

在调试过程中,可能会遇到各种问题,如内存泄漏、访问越界、逻辑错误等。使用调试工具(如GDB)和打印语句可以帮助你定位问题。通过这个项目,学会了如何设计和实现一个复杂的类,并理解如何组织代码以使其易于维护和扩展。此外,还学会了如何编写代码来处理各种情况。

  • 41
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值