C++学习-类和对象

要求:
1.建立一个分数类。分数类的成员包括分子和分母,操作包括约分、通分、加、减、乘、除、复制赋值、求倒数、比较、显示、输入;
2.加(+)、减(-)、乘(*)、除(/)、比较(>, >=, <, <=)、复制赋值(=)的操作采用运算符重载的方式实现;
3.功能要求:能够处理int,double,float型数据与分数类对象的混合运算;
4.测试用例涵盖所有功能(包括分数类之间的运算以及分数类与int,double,float型数据的运算),需包含运行结果图、测试目的说明、运行结果分析;
5.代码整洁、规范
6.附运行结果图,并对测试用例、测试目的、运行结果进行说明与分析
一些相关问题:
1.简述成员函数与友元函数的区别,并分析哪些功能需要用成员函数实现,哪些功能需要用友元函数实现;
①成员函数是类定义的一部分,通过特定的对象来调用。成员函数可以隐式访问调用对象的成员,而无须使用成员操作符。友元函数不是类的组成部分,因此被称为直接函数调用。友元函数不能隐式访问类成员,而必须将成员操作符用于作为参数传递的对象。作为类的非成员函数,而且当要访问的数据为对象的私有成员函数时,则必须声明为类的友元函数。
②当运算符重载函数作为类的成员函数时,要求操作数左边必须是一个对象,而函数的参数可以是同类的对象也可以是普通的变量。
③因为默认的复制赋值运算符是成员函数,友元函数不能取代成员函数,因此复制复制运算符(=)重载也必须为成员函数。而分数类的四则运算,以及比较运算既可以使用成员函数也可以使用友元函数,但涉及到分数类对象与不同数据类型的运算时,必须使用友元函数。
2.简述传值与引用的区别,并分析不同函数所需采用的参数传递方式,并简述原因;
①传值调用传递的是变量的拷贝,而后两种调用传递的则是变量本身,因此传值调用中改变的仅是变量的拷贝,而不是变量本身,相反,当需要改变变量本身的时候就可以用后两种调用。
②当传递的变量很大时,传值调用的结果就是效率低下,因为会经过一个型参到实参的拷贝过程,而后两种调用由于传递的就是变量本身,因此效率会高些。
③传引用调用和传指针调用的区别是引用参数必须指向一个对象,而且在函数中不能改变所指,相反,传指针调用则不存在这个问题,指针开始可以是一个什么都不指向的空指针,而且在函数中可以指向不同的对象。
④对分数类的四则运算及比较运算均为引用的方式不需要创建临时变量,可以提高效率;而复制赋值运算时是传值的形式,不影响实参;
C++代码:

#include<iostream>
#include<cmath>
using namespace std;

class Fraction
{
    
    
    double nume;   //分子
    double deno;   //分母
public:
    Fraction(double nume = 0, double deno = 1);    //默认参数
    void reduction();                           //约分
    void tongfen(Fraction& , Fraction& );     //通分
    void display();                 //显示分数
    void input();                   //输入分数

    //重载四则运算符
    friend Fraction operator +(Fraction& , Fraction&);  //加法
    friend Fraction operator -(Fraction& , Fraction&);  //减法
    friend Fraction operator *(Fraction& , Fraction&);  //乘法
    friend Fraction operator /(Fraction& , Fraction&);  //除法
    Fraction operator =(Fraction);        //复制赋值

    //重载比较操作符
    friend bool operator > (Fraction&, Fraction&);    //大于
    friend bool operator >=(Fraction&, Fraction&);   //大于等于
    friend bool operator < (Fraction&, Fraction&);    //小于
    friend bool operator <=(Fraction&, Fraction&);   //小于等于
};
Fraction::Fraction(double nu, double de)
{
    
    
    nume = nu;
    deno = de;
}
//输入
void Fraction::input()  
{
    
    
    char ch;
    cin >> nume >> ch >> deno;
    while (deno == 0)
    {
    
    
        cout << "分母不能为0,请重新输入:" << endl;
        cin >> nume >> ch >> deno;
    }
    nume *= 1000; //处理小数,只能精确到后三位
    deno *= 1000;
}
//显示
void Fraction::display()    
{
    
    
    reduction();
    if (nume == 0)
        cout << '0' << endl;
    else if (deno == 1)
        cout << nume << endl;
    else
        cout << nume << '/' << deno << endl;
}
//约分
void Fraction::reduction()   
{
    
    
    int m, n, r;
    n = fabs(deno);
    m = fabs(nume);
    r = m % n;
    while (r)  // 求m,n的最大公约数
    {
    
    
        m = n;
        n = r;
        r = m % n;
    }
    deno /= n;     // 化简
    nume /= n;
    if (deno < 0)  // 将分母转化为正数
    {
    
    
        deno = -deno;
        nume = -nume;
    }
}
//通分
void Fraction::tongfen(Fraction& x,Fraction& y)
{
    
    
    x.deno = (x.deno * y.deno);
    x.nume = (x.nume * y.deno);
    reduction();
    cout << x.nume << '/' << x.deno << endl;
}

// 分数复制赋值
Fraction Fraction:: operator=(Fraction f)
{
    
    
    Fraction temp;
    temp.nume = f.nume;
    temp.deno = f.deno;
    nume = temp.nume;
    deno = temp.deno;
    return temp;
}
//加法
Fraction operator+(Fraction& x, Fraction& y)
{
    
    
    Fraction temp;
    temp.nume = x.nume * y.deno + x.deno * y.nume;
    temp.deno = x.deno * y.deno;
    return temp;
}
//减法
Fraction operator-(Fraction& x, Fraction& y)
{
    
    
    Fraction temp;
    temp.nume = x.nume * y.deno - x.deno * y.nume;
    temp.deno = x.deno * y.deno;
    return temp;
}
//乘法
Fraction operator*(Fraction& x, Fraction& y)
{
    
    
    Fraction temp;
    temp.nume = x.nume * y.nume;
    temp.deno = x.deno * y.deno;
    return temp;
}
//除法
Fraction operator/(Fraction& x, Fraction& y)
{
    
    
    Fraction temp;
    temp.nume = x.nume * y.deno;
    temp.deno = x.deno * y.nume;
    return temp;
}
//大于
bool operator >(Fraction& x, Fraction& y)
{
    
    
    if (x.nume * y.deno - x.deno * y.nume > 0)
        return true;
    else
        return false;
}
//大于等于
bool operator >=(Fraction& x, Fraction& y)
{
    
    
    if (x.nume * y.deno - x.deno * y.nume >= 0)
        return true;
    else
        return false;
}
//小于
bool operator <(Fraction& x, Fraction& y)
{
    
    
    if (x.nume * y.deno - x.deno * y.nume < 0)
        return true;
    else
        return false;
}
//小于等于
bool operator <=(Fraction& x, Fraction& y)
{
    
    
    if (x.nume * y.deno - x.deno * y.nume <= 0)
        return true;
    else
        return false;
}
//主函数
int main() {
    
    
    Fraction x, y, s;
    cout << "请输入x:" << endl;
    x.input();
    cout << "请输入y:" << endl;
    y.input();
    s = x + y;
    cout << "x+y="; s.reduction(); s.display();
    s = x - y;
    cout << "x-y="; s.display();
    s = x * y;
    cout << "x*y="; s.display();
    s = x / y;
    cout << "x/y="; s.display();
    s = x > y;
    cout << "x>y的结果true为1,false为0:"; s.display();
    s = x >= y;
    cout << "x>=y的结果true为1,false为0:"; s.display();
    s = x < y;
    cout << "x<y的结果true为1,false为0:"; s.display();
    s = x <= y;
    cout << "x<=y的结果true为1,false为0:"; s.display();
    cout << "x对y通分结果为:"; x.tongfen(x, y);
    s = x = y;
    cout << "x=y="; s.display();
}

运行结果:
在这里插入图片描述
目前方法不足与局限:
1)处理double型和float型数据时偷懒了,直接乘与1000,相当于转成int型了,因此只能计算到小数点后三位;如果改进的话,可以输入字符串的形式,再进行转换;
显示的时候,没有对比较运算的结果进行处理,只显示了0和1,没有转换成true或者false,便于查看与理解。

猜你喜欢

转载自blog.csdn.net/weixin_46837674/article/details/113030741
今日推荐