代码如下:
/* *这个文件包含了Rational类的声明 ,也包含了这个类的对应的重载运算符的自由 *函数的声明。 */ #ifndef _Rational_h #define _Rational_h class Rational{ public: /* *构造函数:Rational *用法: Rational R; Rational R1(n); Rational R2(x,y); *----------------------- * 创建一个Rational对象,默认构造的值为0,当只有一个参数n时候, *构造的是一个等值于这个数的Rational值。当含有两个参数的时候, *创建的是分数 x/y */ Rational(); Rational(int n); Rational(int x, int y); /* *方法:toString *用法:string str = r.toString(); *------------------------------- *将值以字符串的形式呈现出来 */ std::string toString(); #include "rationalpriv.h" }; /* *运算符:<< *----------- *重载运算符,使得可以按分数的形式出现 */ std::ostream & operator<<(std::ostream & os, Rational rat); /* *运算符 :+ *用法:r1 + r2; *---------------- *重载运算符+,使得它可以进行分数之间的相加的运算,返回计算后的结果 */ Rational operator+(Rational r1, Rational r2); /* *运算符 :- *用法:r1 - r2; *---------------- *重载运算符-,使得它可以进行分数之间的相减运算,返回计算后的结果 */ Rational operator-(Rational r1, Rational r2); /* *运算符 :* *用法:r1 * r2; *---------------- *重载运算符+,使得它可以进行分数之间的相乘运算,返回计算后的结果 */ Rational operator*(Rational r1, Rational r2); /* *运算符 :/ *用法:r1 / r2; *---------------- *重载运算符/,使得它可以进行分数之间的相除运算,返回计算后的结果 */ Rational operator/(Rational r1, Rational r2); #endif代码如下:
/* *这部分内容为Rational类的私有部分成员或不希望被用户看到的内容 *将运算符以friend形式声明 */ friend Rational operator+(Rational r1, Rational r2); friend Rational operator-(Rational r1, Rational r2); friend Rational operator*(Rational r1, Rational r2); friend Rational operator/(Rational r1, Rational r2); private: /*实例化参数*/ int num;//分子 int den;//分母这里可能会有疑问,就是我们这里已经声明了Rational operator+(Rational r1, Rational r2);这些函数,为何我们还要在上面头文件的Rational类后面再次声明呢?答案是,我们在这里声明的东西依旧属于类内,是为了声明类与这个自由函数的关系是friend。而Rational.h文件在Rational后面声明的才是函数的原型,自由函数不属于某个类,但是它可以和某个类有某种关系。
代码如下:
#include <cstdlib> #include <cmath> #include "error.h" #include "rational.h" #include "strlib.h" using namespace std; /*函数原型*/ int gcd(int x, int y); /*构造函数*/ Rational::Rational(){ num = 0; den = 1; } Rational::Rational(int n){ num = n; den = 1; } Rational::Rational(int x, int y) { if (y == 0) error("错误,分母不能为0"); if (x == 0) { num = 0; den = 1; } else { int g = gcd(abs(x), abs(y)); num = x / g; den = abs(y) / g; if (y < 0) num = -num; } } /*实现toString函数*/ string Rational::toString(){ if(den == 1) { //如果这里我们写成了 = 会出现什么情况? return integerToString(num); }else{ return integerToString(num) + "/" + integerToString(den); } } /*实现插入运算符<<的重载*/ ostream & operator<<(ostream & os, Rational rat){ return os << rat.toString(); } /*实现 + - * / 的重载*/ Rational operator+(Rational r1, Rational r2) { return Rational(r1.num * r2.den + r2.num * r1.den, r1.den * r2.den); } Rational operator-(Rational r1, Rational r2) { return Rational(r1.num * r2.den - r2.num * r1.den, r1.den * r2.den); } Rational operator*(Rational r1, Rational r2) { return Rational(r1.num * r2.num, r1.den * r2.den); } Rational operator/(Rational r1, Rational r2) { return Rational(r1.num * r2.den, r1.den * r2.num); } /* *函数:gcd(great command devision) *用法; int n = gcd(x,y) *----------------------- *求x,y 的最大公约数 */ int gcd(int x, int y) { int r = x % y; while (r != 0) { x = y; y = r; r = x % y; } return y; }这里我在编码的时候,犯了一个小失误,if(den == 1)写成了 if(den = 1),程序不会报错,可以正常运行,但是会出现结果有问题,至于是什么就自己去试试了。可以在测试代码一这里运行。至于为什么会这样,可以留言。我会回复。 这里涉及到两个自定义的头文件 关于”strlib.h”,参考:C++抽象编程——自定义strlib文件 关于”error.h”,看下面:
测试结果如下:
测试结果如下: