C++:专题六实验(运算符重载、友元函数)

C++:专题六实验(运算符重载、友元函数)

Tips:如果你有看不懂的地方,欢迎<私信我> 或者<百度搜索c++菜鸟教程>,提问是解决问题的最好办法!

实验目的:

  1. 学习类的运算符重载的基本方法
  2. 掌握常见的算术运算符和逻辑运算符的重载的方法,包括以成员函数方式重载和非成员方式重载两种方法;
  3. 学习输入输出流运算符的重载,理解其重载过程中的参数、返回值和重载方式;
  4. 学习赋值运算符、下标运算符的重载方法,学习一元求反运算符的重载方法及其与减法运算符重载的区别,学习前置/后置自增/自减运算符的重载方法及运用

实验内容:

  1. 任何有理数都可以表示为“分子/分母”的方式,其中分子、分母都是整数。实现一个有理数类,为这个有理数类重载四则运算(+、-、*、/)和所有的比较逻辑运算符(==、!=、>=、>、<=、<)所有重载均以类的成员函数的方式实现。
  2. 定义一个表示复数的Complex类,包含实部和虚部的两个属性。在类的外部以友元函数的形式重载+、-、*等运算符。要求在数函数中给出测试程序,运算结果要符合数学意义。接下来,为其重载输入输出流。以使用cin和cout关键字对Complex的对象进行输入输出。
  3. 实现一个时钟类Clock。包含时、分、秒三个属性。重载其赋值运算符(=)和自增运算符(自减运算符因为没有实际意义,本题中不予实现)。并给出测试语句证明其正确性。
(一)任何有理数都可以表示为“分子/分母”的方式,其中分子、分母都是整数。实现一个有理数类,为这个有理数类重载四则运算(+、-、*、/)和所有的比较逻辑运算符(==、!=、>=、>、<=、<)所有重载均以类的成员函数的方式实现。
#include <iostream>
#include <cstring>

using namespace std;

class Rational
{
private:

    int numerator, denominator; //分子和分母

public:

    Rational(int n = 1, int d = 1); //构造函数(注意需要有默认参数)

    void simplify();//最简化分数函数

    string show();//输出分数

    Rational operator+(const Rational& num);//此处参见知识点:运算符的重载
    Rational operator-(const Rational& num);
    Rational operator*(const Rational& num);
    Rational operator/(const Rational& num);

    bool operator >(const Rational& num);//此处参见知识点:关系运算符的重载
    bool operator <(const Rational& num);
    bool operator >=(const Rational& num);
    bool operator <=(const Rational& num);
    bool operator ==(const Rational& num);
    bool operator !=(const Rational& num);
};

Rational::Rational(int n, int d) //定义构造函数
{
    numerator = n, denominator = d;
    simplify();
}

void Rational::simplify()//定义最简化函数
{
    bool isNegative = false;//判断是否为负分数

    if(numerator < 0)//分数小于零时,把分数去负号
    {
        isNegative = true;
        numerator = -numerator;
    }

    int t = numerator <= denominator ? numerator : denominator;

    if(numerator == 0)//有理数为0
    {
        denominator = 1; //分母设为1,便于运算与输出
    }

    if(numerator > 0)//分数大于零时
    {
        for(int i = t; i >= 2; i--)
            if(numerator % i == 0 && denominator % i == 0)
                numerator /= i, denominator /= i;
    }


    if(isNegative)//分数小于零,再添上负号
        numerator = -numerator;
}

string Rational::show()//定义输出函数
{
    simplify();

    if(denominator != 1)
        return " " + to_string(numerator) + "/" + to_string(denominator) + " ";
    else
        return " " + to_string(numerator) + " ";
}

Rational Rational:: operator+(const Rational& num)//重新定义加法
{
    Rational r;
    //注意,这里写this->numerator(this是个指针,指向是调用此函数的对象)或者直接写numerator,不用r.numerator,否则会使用局部变量r的值
    r.numerator = this->numerator * num.denominator + num.numerator * this->denominator;
    r.denominator = this->denominator * num.denominator;
    r.simplify();
    return r;
}

Rational Rational:: operator-(const Rational& num)//重新定义减法
{
    Rational r;
    r.numerator = this->numerator * num.denominator - num.numerator * this->denominator;
    r.denominator = this->denominator * num.denominator;
    r.simplify();
    return r;
}

Rational Rational:: operator*(const Rational& num)//重新定义乘法
{
    Rational r;
    r.numerator = this->numerator * num.numerator;
    r.denominator = this->denominator * num.denominator;
    r.simplify();
    return r;
}

Rational Rational:: operator/(const Rational& num)//重新定义除法
{
    Rational r;
    r.numerator = this->numerator * num.denominator;
    r.denominator = this->denominator * num.numerator;
    r.simplify();
    return r;
}

bool Rational:: operator >(const Rational& num)
{
    if(numerator * num.denominator - denominator * num.numerator > 0)
        return true;
    else
        return false;
}

bool Rational:: operator <(const Rational& num)
{
    if(this->numerator * num.denominator - this->denominator * num.numerator < 0)
        return true;
    else
        return false;
}

bool Rational:: operator >=(const Rational& num)
{
    if(this->numerator * num.denominator - this->denominator * num.numerator >= 0)
        return true;
    else
        return false;
}

bool Rational:: operator <=(const Rational& num)
{
    if(this->numerator * num.denominator - this->denominator * num.numerator <= 0)
        return true;
    else
        return false;
}

bool Rational:: operator ==(const Rational& num)
{
    if(this->numerator * num.denominator - this->denominator * num.numerator == 0)
        return true;
    else
        return false;
}

bool Rational:: operator !=(const Rational& num)
{
    if(this->numerator * num.denominator - this->denominator * num.numerator != 0)
        return true;
    else
        return false;
}

int main()
{
    int a1, a2, b1, b2;
    cout << "请输入有理数a(分子 分母格式):" << endl;
    cin >> a1 >> a2;
    cout << "请输入有理数b(分子 分母格式):" << endl;
    cin >> b1 >> b2;
    Rational a(a1, a2);
    Rational b(b1, b2);
    Rational c1 = a + b;
    Rational c2 = a - b;
    Rational c3 = a * b;
    Rational c4 = a / b;
    cout << "输出结果如下:" << endl;
    cout << a.show() << "+" << b.show() << "=" << c1.show() << endl;
    cout << a.show() << "-" << b.show() << "=" << c2.show() << endl;
    cout << a.show() << "*" << b.show() << "=" << c3.show() << endl;
    cout << a.show() << "/" << b.show() << "=" << c4.show() << endl;
    string o[6] = {">", "<", ">=", "<=", "==", "!="};
    string t[6];

    for(int i = 0; i < 6; i++)
        t[i] = "false";

    if(a > b)
        t[0] = "true";

    if(a < b)
        t[1] = "true";

    if(a >= b)
        t[2] = "true";

    if(a <= b)
        t[3] = "true";

    if(a == b)
        t[4] = "true";

    if(a != b)
        t[5] = "true";

    for(int i = 0; i < 6; i++)
        cout << a.show() << o[i] << b.show() << "is " << t[i] << endl;

    return 0;
}

在这里插入图片描述
在这里插入图片描述

(二)定义一个表示复数的Complex类,包含实部和虚部的两个属性。在类的外部以友元函数的形式重载+、-、*等运算符。要求在数函数中给出测试程序,运算结果要符合数学意义。接下来,为其重载输入输出流。以使用cin和cout关键字对Complex的对象进行输入输出。
#include <iostream>

using namespace std;

class Complex
{
private:
    double real, image;
public:
    Complex(double r, double i);
    //知识点:运算符的重载、友元函数
    friend Complex operator +(Complex a, Complex b);
    friend Complex operator -(Complex a, Complex b);
    friend Complex operator *(Complex a, Complex b);
    friend Complex operator /(Complex a, Complex b);

    //知识点:输入输出运算符的重载:
    friend ostream &operator <<(ostream &output, const Complex &C);
    friend istream &operator >>(istream &input, Complex &C);
};

Complex::Complex(double r = 0, double i = 0)
{
    real = r, image = i;
}

Complex operator +(Complex a, Complex b)
{
    Complex c;
    c.real = a.real + b.real;
    c.image = a.image + b.image;
    return c;
}
Complex operator -(Complex a, Complex b)
{
    Complex c;
    c.real = a.real - b.real;
    c.image = a.image - b.image;
    return c;
}
Complex operator *(Complex a, Complex b)
{
    Complex c;
    c.real = a.real * b.real - a.image * b.image;
    c.image = a.real * b.image + a.image * b.real;
    return c;
}
Complex operator /(Complex a, Complex b)
{
    Complex c;
    c.real = (a.real * b.real + a.image * b.image) / (b.real * b.real + b.image * b.image);
    c.image = (a.image * b.real - a.real * b.image) / (b.real * b.real + b.image * b.image);
    return c;
}

ostream &operator <<(ostream &output, const Complex &C)
//为啥加上const?
//我们不希望在这个函数中对用来进行赋值的“原版”做任何修改。函数加上const后缀的作用是表明函数本身不会修改类成员变量。
//加上const,对于const和非const的实参,函数都能接受;如果不加,就只能接受非const的实参。
{
    if(C.real != 0)
    {
        if(C.image > 0)
            output << C.real << "+" << C.image << "i";
        else if(C.image < 0)
            output << C.real << C.image << "i";
        else
            output << C.real;
    }
    else
    {
        if(C.image != 0)
            output << C.image << "i";
        else
            output << 0;
    }

    return output;
}

istream &operator >>(istream &input, Complex &C)//为啥这里不用const?
{
    input >> C.real >> C.image;
    return input;
}
int main()
{
    Complex x, y;
    cout << "请输入复数x:";
    cin >> x;
    cout << "请输入复数y:";
    cin >> y;
    cout << "x + y = " << x + y << endl;
    cout << "x - y = " << x - y << endl;
    cout << "x * y = " << x*y << endl;
    cout << "x / y = " << x / y << endl;
    return 0;
}

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

(三)实现一个时钟类Clock。包含时、分、秒三个属性。重载其赋值运算符(=)和自增运算符(自减运算符因为没有实际意义,本题中不予实现)。并给出测试语句证明其正确性。
#include <iostream>
#include <iomanip>

using namespace std;

class Clock
{
public:
    int hour, minute, second;

    Clock(int h, int m, int s);
    Clock run();//定义一个加一秒的函数
    void show();//定义一个打印变量的函数

    //知识点:自增++和自减--运算符的重载
    Clock operator++();//++i,前置形式
    Clock operator++(int);//i++,后置形式,这里的int没有意义,只是用来区分前置和后置形式
    //Clock operator--();
    //Clock operator--(int);

    //知识点:赋值运算符的重载
    void operator=(const Clock &C);
};

Clock::Clock(int h = 0, int m = 0, int s = 0)
{
    hour = h, minute = m, second = s;
}

Clock Clock::run()
{
    ++second;
    if(second == 60)
    {
        ++minute;
        second -= 60;

        if(minute == 60)
        {
            ++hour;
            minute -= 60;

            if(hour == 24)
                hour -= 24;
        }
    }
    return *this;
}

void Clock::show()
{
    cout << setw(2) << setfill('0') << hour << ":" << setw(2) << setfill('0') << minute << ":" << setw(2) << setfill('0') << second << endl;
}

//前置++指先实现对象的自增,再返回自增后的对象
Clock Clock::operator++()//重载前缀++
{
    return run();
}

//后置++指先返回对象本身,再实现对象的自增
Clock Clock::operator++(int)//重载后缀++
{
    Clock C = *this;
    this->run();
    return C;
}

void Clock::operator=(const Clock &C)
{
    this->hour = C.hour;
    this->minute = C.minute;
    this->second = C.second;
}

int main()
{
    int h, m, s;
    cout << "请输入一个时间(时 分 秒):";
    cin >> h >> m >> s;
    Clock A(h, m, s);
    Clock B;
    Clock C;
    Clock D;
    cout << "Clock A: ", A.show();
    cout << "Clock B: ", B.show();
    cout << "Clock C: ", C.show();
    cout << "Clock D: ", D.show();
    cout << endl;
    B = ++A;
    cout << "B = ++A;" << endl;
    cout << "Clock A: ", A.show();
    cout << "Clock B: ", B.show();
    cout << endl;
    C = A++;
    cout << "C = A++;" << endl;
    cout << "Clock A: ", A.show();
    cout << "Clock C: ", C.show();
    cout << endl;
    D = A;
    cout << "D = A;" << endl;
    cout << "Clock A: ", A.show();
    cout << "Clock D: ", D.show();
    cout << endl;
    return 0;
}

在这里插入图片描述
在这里插入图片描述
友情提示:《实验一》中代码如果使用低版本codeblocks运行,编译时可能会出现to_string函数报错。此时请使用其他编译器或高版本codeblocks运行(博主使用20.03版本 点击下载安装说明)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值