C++学习之友元函数,操作符重载

这是我写的第一个类,分数类型,虽然比较简单,但我犯的错也并不少,比方成员函数和全局函数打代码时总是搞混,输入负的分数时也出现各种变态的输出,还发现了一个以前不知道的知识点就是 a*1.0/b 和a/b*1.0不一样,收获不小,留下代码供复习用。

#include<iostream>
#include<cmath>

using namespace std;

class fraction
{
public:
    fraction():mole(0),deno(1) {};
    fraction(int,int);
    fraction(double);
    void print();
    friend istream&operator>>(istream&,fraction&);
    friend ostream&operator<<(ostream&,const fraction&);
    friend fraction operator+(const fraction&,const fraction&);
    friend fraction operator-(const fraction&,const fraction&);
    friend fraction operator*(const fraction&,const fraction&);
    friend fraction operator/(const fraction&,const fraction&);
    friend fraction operator!(const fraction&);

    friend bool operator <=(const fraction&,const fraction&);
    friend bool operator >=(const fraction&,const fraction&);
    friend bool operator <(const fraction&,const fraction&);
    friend bool operator >(const fraction&,const fraction&);
    friend bool operator ==(const fraction&,const fraction&);
    friend bool operator !=(const fraction&,const fraction&);


    fraction& operator++();
    const fraction operator++(int);
    fraction operator-()const;
    fraction& operator--();
    const fraction operator--(int);
    operator double()const;
    fraction& operator+=(const fraction&);
    fraction& operator-=(const fraction&);
    fraction& operator*=(const fraction&);
    fraction& operator/=(const fraction&);

private:
    int mole;
    int deno;
    void set(int,int);
    static int gcd(const int&,const int &);
};

fraction::fraction(int a,int b)
{
    set(a,b);
}

fraction::fraction(double a)
{
    mole=0,deno=1;
    int flag=a>0?1:-1;
    a=fabs(a);
    while(fabs(mole*1.0/deno-a)>0.001)
    {
        if(mole*1.0/deno<a)mole++;
        else deno++;
    }
    mole*=flag;
}

int fraction::gcd(const int& a,const int& b)
{
    return b==0?a:gcd(b,a%b);
}

void fraction::print()
{
    cout<<mole<<"/"<<deno<<endl;
}

void fraction::set(int a,int b)
{
    int t=gcd(a,b);
    mole=a/t;
    deno=b==0?1:b/t;
}

fraction fraction::operator -()const
{
    return fraction(-mole,deno);
}

fraction operator+(const fraction&a,const fraction&b)
{
    int z=a.mole*b.deno+b.mole*a.deno;
    int m=a.deno*b.deno;
    return fraction(z,m);
}

fraction operator-(const fraction&a,const fraction&b)
{
    int z=a.mole*b.deno-b.mole*a.deno;
    int m=a.deno*b.deno;
    return fraction(z,m);
}

fraction operator*(const fraction&a,const fraction&b)
{
    int z=a.mole*b.mole;
    int m=a.deno*b.deno;
    return fraction(z,m);
}

fraction operator/(const fraction&a,const fraction&b)
{
    int z=a.mole*b.deno;
    int m=a.deno*b.mole;
    return fraction(z,m);
}

fraction& fraction::operator++()
{
    mole+=deno;
    return *this;
}

fraction& fraction::operator--()
{
    mole-=deno;
    return *this;
}

const fraction fraction::operator--(int)
{
    fraction t=*this;
    mole-=deno;
    return t;
}

const fraction fraction::operator++(int)
{
    fraction t=*this;
    mole+=deno;
    return t;
}

fraction operator!(const fraction& a)
{
    return fraction(a.deno,a.mole);
}

istream& operator>>(istream& in,fraction& a)
{
    int mole=0,deno=1;
    in>>mole;
    in.ignore();
    in>>deno;
    if(mole*1.0/deno<0)
    a.set(mole,fabs(deno));
    else
    a.set(fabs(mole),fabs(deno));
    return in;
}

ostream& operator<<(ostream& out,const fraction& b)
{
    if(b.mole/b.deno<0)out<<'-';
    out<<fabs(b.mole);
    if(b.mole&&b.deno!=1)
    {
        out<<'/';
        out<<fabs(b.deno);
    }
    return out;
}

fraction::operator double()const
{
    return mole*1.0/deno;
}

bool operator <=(const fraction& a,const fraction& b)
{
    return a.mole*b.deno<=b.mole*a.deno;
}

bool operator >=(const fraction&a,const fraction&b)
{
    return a.mole*b.deno>=b.mole*a.deno;
}

bool operator <(const fraction&a,const fraction&b)
{
    return a.mole*b.deno<b.mole*a.deno;
}

bool operator >(const fraction&a,const fraction&b)
{
    return a.mole*b.deno>b.mole*a.deno;
}

bool operator ==(const fraction&a,const fraction&b)
{
    return a.mole*b.deno==b.mole*a.deno;
}

bool operator !=(const fraction&a,const fraction&b)
{
    return a.mole*b.deno!=b.mole*a.deno;
}

fraction& fraction::operator +=(const fraction& other)
{
    mole=mole*other.deno+deno*other.mole;
    deno=deno*other.deno;
    int t=gcd(mole,deno);
    mole/=t;
    deno/=t;
    return *this;
}

fraction& fraction::operator -=(const fraction& other)
{
    mole=mole*other.deno-deno*other.mole;
    deno=deno*other.deno;
    int t=gcd(mole,deno);
    mole/=t;
    deno/=t;
    return *this;
}

fraction& fraction::operator *=(const fraction& other)
{
    mole*=other.mole;
    deno*=other.deno;
    int t=gcd(mole,deno);
    mole/=t,deno/=t;
    return *this;
}

fraction& fraction::operator /=(const fraction& other)
{
    mole*=other.deno;
    deno*=other.mole;
    int t=gcd(mole,deno);
    mole/=t,deno/=t;
    return *this;
}

int main()
{
    fraction a,b;
    cout<<"求倒数:"<<endl;
    cin>>a;
    cout<<"!a:"<<!a<<endl<<endl;

    cout<<"强制转换:"<<endl;
    cin>>a;
    cout<<"double(a)"<<double(a)<<endl;

    cout<<"自加自减:"<<endl;
    cin>>a;
    cout<<"a++:"<<a++<<endl;
    cout<<"a:"<<a<<endl;
    cout<<"++a:"<<++a<<endl;
    cout<<"a:"<<a<<endl<<endl;

    cout<<"基本运算:"<<endl;
    cin>>a>>b;
    cout<<"a+b:"<<a+b<<endl;
    cout<<"a/b:"<<a/b<<endl;
    cout<<"a*b:"<<a*b<<endl;
    cout<<"a-b:"<<a-b<<endl;
    cout<<"a+=b"<<(a+=b)<<endl;
    cout<<"a="<<a<<"b="<<b<<endl;
    cout<<"a-=b"<<(a-=b)<<endl;
    cout<<"a="<<a<<"b="<<b<<endl;
    cout<<"a*=b"<<(a*=b)<<endl;
    cout<<"a="<<a<<"b="<<b<<endl;
    cout<<"a/=b"<<(a/=b)<<endl<<endl;

    cout<<"关系比较:"<<endl;
    cin>>a>>b;
    cout<<"a>=b:"<<(a>=b)<<endl;
    cout<<"a<=b:"<<(a<=b)<<endl;
    cout<<"a>b:"<<(a>b)<<endl;
    cout<<"a<b:"<<(a<b)<<endl;
    cout<<"a!=b:"<<(a!=b)<<endl;

    return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值