运算符重载例题

用的是vs2019编译器

这是一个有关运算符重载的例题,希望大家作以参考

定义有理数类(分母不为0的分数,分子分母均为整数)Rational,实现相应操作符的重载。
(1)定义私有数据成员分子int iUp ; 分母int iDown
(2)定义私有成员函数void Reduce()int Gcd(int l, int r),分别用于有理数的约简求两个整数的最大公约数。其中,在约简时需要求取分子与分母的最大公约数。
(3)定义构造函数,在构造函数体内可调用Reduce对有理数进行约简。
(4)将负号-和赋值运算符=重载为公有成员函数,分别用于求有理数的负数和赋值。
(5)将前置++、前置–、后置++、后置–重载为公有成员函数,实现有理数自增1或自减1。
(6)将+、-、*、/重载为友员函数,实现有理数的加减乘除。
(7)将<、<=、>、>=重载为友员函数,实现有理数的大小关系比较。
(8)重载流插入符<<和流提取符>>,分别用于有理数的输出和输入。其中,输出格式为“分子/分母”,若为整数,则直接输出整数。
在main函数中,根据输入的分子和分母定义两个有理数对象a和b。再定义几个有理数对象分别用于表示a和b的加、减、乘、除、前置自增a、前置自减a、后置自增a、后置自减a,并依次各个对象的结果。最后依次用<、<=、>、>=比较a和b的大小关系,并依次输出比较结果(true或false)。

输入

两个有理数a和b的的分子和分母

输出

有理数a和b的加、减、乘、除以及前置自增a、前置自减a、后置自增a、后置自减a有理数a和b的<、<=、>、>=的结果

样例输入

4 3
3 2

样例输出

a+b: 17/6
a-b: -1/6
a*b: 2
a/b: 8/9
-a: -4/3
++a: 7/3
–a: 4/3
a++: 4/3
a–: 7/3
a<b: true
a<=b: true
a>b: false
a>=b: false

下面展示此题代码

#include <iostream>
using namespace std;

class Rational{
    friend Rational operator+(Rational& p1, Rational& p2);
    friend Rational operator-(Rational& p1, Rational& p2);
    friend Rational operator*(Rational& p1, Rational& p2);
    friend Rational operator/(Rational& p1, Rational& p2);
    friend bool operator<(Rational& p1, Rational& p2);
    friend bool operator<=(Rational& p1, Rational& p2);
    friend bool operator>(Rational& p1, Rational& p2);
    friend bool operator>=(Rational& p1, Rational& p2);
    friend ostream& operator <<(ostream& cout, Rational& p);
    friend istream& operator >>(istream& cin, Rational& p);
private:
    int iUp;
    int iDown;
    
    //有理数约简
    void Reduce() {
        int t = abs(Gcd(iUp, iDown));
        iUp = iUp / t;
        iDown = iDown / t;
        if (iDown < 0){
            iDown = -iDown; 
            iUp = -iUp; 
        }
    }

    int Gcd(int l, int r) {
        int temp = l % r;
        while (temp != 0) {
            l = r;
            r = temp;
            temp = l % r;
        }

        return r;
    }
    
public:
    Rational() {
        iUp = 1;
        iDown = 1;
    }
    Rational(int a,int b) {
        iUp = a;
        iDown = b;
        Reduce();
    }
	//相反数
    Rational operator-()  { 
        Rational temp;
        temp.iUp = -iUp;
        temp.iDown = iDown;
        return temp;
    }
	//赋值    
    Rational& operator=(const Rational& p) {
        iUp = p.iUp;
        iDown = p.iDown;
        Reduce();
        return *this;
    }
    //前置++
    Rational& operator++() {
        iUp += iDown;
        Reduce();
        return *this;
    }
    //前置--
    Rational& operator--() {
        iUp -= iDown;
        return *this;
    }
    //后置++
    Rational operator++(int) {
        Rational temp = *this;
        iUp += iDown;
        return temp;
    }
    //后置--
    Rational operator--(int) {
        Rational temp = *this;
        iUp -= iDown;
        return temp;
    }  
   
};
//加法+
Rational operator+(Rational& p1, Rational& p2) {
    Rational temp;
    temp.iDown = p1.iDown * p2.iDown;
    temp.iUp = p1.iUp * p2.iDown + p2.iUp * p1.iDown;
    temp.Reduce();
    return temp;
}
//减法-
Rational operator-(Rational& p1, Rational& p2) {
    Rational temp;
    temp.iDown = p1.iDown * p2.iDown;
    temp.iUp = p1.iUp * p2.iDown - p2.iUp * p1.iDown;
    temp.Reduce();
    return temp;
}
//乘法*
Rational operator*(Rational& p1, Rational& p2) {
    Rational temp;
    temp.iUp = p1.iUp * p2.iUp;
    temp.iDown = p1.iDown * p2.iDown;
    temp.Reduce();
    return temp;
}
//除法/
Rational operator/(Rational& p1, Rational& p2) {
    Rational temp;
    temp.iUp = p1.iUp * p2.iDown;
    temp.iDown = p1.iDown * p2.iUp;
    temp.Reduce();
    return temp;
}
//<号
bool operator<(Rational& p1, Rational& p2) {
    int temp;
    temp = p1.iDown * p2.iDown;
    p1.iDown = temp;
    p1.iUp += p2.iDown;
    p2.iDown = temp;
    p2.iUp += p1.iDown;
    p1.Reduce();
    p2.Reduce();
    if (p1.iUp < p2.iUp) {
        return true;
    }
    return false;
}
bool operator<=(Rational& p1, Rational& p2) {
    int temp;
    temp = p1.iDown * p2.iDown;
    p1.iDown = temp;
    p1.iUp += p2.iDown;
    p2.iDown = temp;
    p2.iUp += p1.iDown;
    p1.Reduce();
    p2.Reduce();
    if (p1.iUp <= p2.iUp) {
        return true;
    }
    return false;
}
bool operator>(Rational& p1, Rational& p2) {
    int temp;
    temp = p1.iDown * p2.iDown;
    p1.iDown = temp;
    p1.iUp += p2.iDown;
    p2.iDown = temp;
    p2.iUp += p1.iDown;
    p1.Reduce();
    p2.Reduce();
    if (p1.iUp > p2.iUp) {
        return true;
    }
    return false;
}
bool operator>=(Rational& p1, Rational& p2) {
    int temp;
    temp = p1.iDown * p2.iDown;
    p1.iDown = temp;
    p1.iUp += p2.iDown;
    p2.iDown = temp;
    p2.iUp += p1.iDown;
    p1.Reduce();
    p2.Reduce();
    if (p1.iUp >= p2.iUp) {
        return true;
    }
    return false;
}
ostream& operator <<(ostream& cout, Rational& p) {
    int temp;
    if (p.iUp % p.iDown == 0) {
        cout << p.iUp / p.iDown <<endl;
    }else {
        cout << p.iUp << "/" << p.iDown << endl;
    }
    return cout;
}
istream& operator >>(istream& cin, Rational& p) {
    cin >> p.iUp >> p.iDown;
    //cout << p.iUp << "/" << p.iDown << endl;
    return cin;
}


int main()
{
    Rational a;
    Rational b;
    cin >> a;
    cin >> b;
    Rational c;				
    c = a + b;
    cout << "a+b: " << c ;
    c = a - b;
    cout << "a-b: " << c;
    c = a * b;
    cout << "a*b: " << c;
    c = a / b;
    cout << "a/b: " << c;
    c = -a;
    cout << "-a: " << c ;
    cout << "++a: " << ++a ;
    cout << "--a: " << --a ;
    c = a++;
    cout << "a++: " << c ;
    c = a--;
    cout << "a--: " << c ;
    bool d;
    d = (a < b);
    cout << "a<b: " << boolalpha << d << endl;
    d = (a <= b);
    cout << "a<=b: " << boolalpha << d<< endl;
    d = (a > b);
    cout << "a>b: " << boolalpha << d << endl;
    d = (a >= b);
    cout << "a>=b: " << boolalpha << d << endl;
    system("pause");
}




对于这个题本人遇到的一些小问题

  1. 为什么在最后输出的时候引入了新的值cd
    因为在重载<<和>>时,传入的是一个类对象的引用。例如,若直接写成
    cout<<"a+b: "<< a + b << endl ;则会造成重载的其实是a + b这两个类对象的重载的加运算。

  2. 对于返回类类型的运算符重载来说,为什么有的返回的是类类型的引用?
    以上代码在进行加减乘除时,都在重载函数内用了临时的类类型变量temp,所以如果用返回引用的话,编译器会报错,因为temp的生命周期只是在函数内,无法传它的引用到外界。而在前置++赋值=前置– 中,返回的是传入值的本身,所以要用引用返回。

  3. 关于void Reduce()函数在每一个二元运算中的调用。
    调用的原因其实很简单,但是会很容易忽视。因为在二元运算后,可能会改变分子分母的符号,所以必须调用此函数,来调整输出,以保证如果是负数,输出时负号是在分子前面的,也可以调用此函数进行上下都是负数,从而约简成都是正数。

  • 5
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
(有理数)创建一个名为 Rational 的类,用于对分数进行算术运算。编写一个程序来测试你的类。使用整数变量来表示类的私有实例变量——分子和分母。 提供一个构造函数,使该类的对象能够在声明时进行初始化。构造函数应以简化形式存储分数。分数 2/4 等价于 1/2,并将作为分子中的 1 和分母中的 2 存储在对象中。 如果没有提供初始值设定项,请提供默认值为 1 的无参数构造函数。 提供执行以下每个操作的公共方法: a) 将两个有理数相加:相加的结果应以简化形式存储。 b) 两个有理数相减:相减的结果应以简化形式存储。 c) 将两个有理数相乘:相乘的结果应以简化形式存储。 d) 将两个有理数相除:相除的结果应以简化形式存储。 e) 以 a/b 的形式返回有理数的字符串表示形式,其中 a 是分子,b 是分母。 f) 以浮点格式返回有理数的字符串表示形式. (考虑提供格式化功能,类的用户能够指定小数点右侧的精度位数。) 【Sample output 1】 Enter numerator 1: 12 Enter denominator 1: 3 Enter numerator 2: 5 Enter denominator 2: 14 Enter precision: 3 a=4/1 b=5/14 a + b = 61/14 = 4.357 a - b = 51/14 = 3.643 a * b = 10/7 = 1.429 a / b = 56/5 = 11.200 【Sample output 2】 Enter numerator 1: 1 Enter denominator 1: 4 Enter numerator 2: 75 Enter denominator 2: 35 Enter precision: 1 a=1/4 b=15/7 a + b = 67/28 = 2.4 a - b = -53/28 = -1.9 a * b = 15/28 = 0.5 a / b = 7/60 = 0.1 Note: The red texts are inputed ,others are output texts. Just use a space to seperate words
1、抽象类与操作符重载 定义表示形状的抽象类及相应的派生类,并实现相关操作符重载。 (1)定义表示形状的抽象类Shape: 添加公有成员函数double Area(),用于计算形状面积;定义为纯虚函数; 添加公有成员函数void Show(),用于显示形状信息,定义为纯虚函数; 定义虚的析构函数; 重载比较操作符:==、>和<,用于比较两个形状面积的大小关系,返回值类型为bool,可以定义为成员函数或友元函数。 、、、、、、 2、虚函数 利用虚函数实现多态: (1)设计Person类,要求具有用于表示姓名的保护数据成员:string szName; 实现信息打印的公有成员函数:void Print()。其中,Print函数设计为虚函数,输出的信息格式为:“Person 姓名”。 、、、、、、 3、操作符重载 定义有理数类(分母不为0的分数,分子分母均为整数)Rational,实现相应操作符的重载。 (1)定义私有数据成员:分子int iUp; 分母 int iDown。 (2)定义私有成员函数:void Reduce() 和 int Gcd(int l, int r),分别用于有理数的约简和求两个整数的最大公约数。其中,在约简时需要求取分子与分母的最大公约数。 、、、、、、 4、记录文件的读写操作 源数据文件(文本格式)中包含有每个学生的记录:ID(身份识别号)、 Gender(性别)、 Birthday(生日)和EnrollmentDate(入学时间),字段之间以半角逗号分隔,记录之间以换行符分隔。要求从源数据文件中读取学生记录并删除重复记录,然后根据ID大小对所有记录按从小到大排序,将排序后的记录保存到目标文件中并同时输出到屏幕上。 、、、、、、 5、简单文本文件的读写 、、、、、

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值