首页 > 编程语言 >C++快速入门 第二十七讲:运算符左移<<重载

C++快速入门 第二十七讲:运算符左移<<重载

时间:2023-08-18 15:14:41浏览次数:42  
标签:denominator int rhs 左移 numerator C++ 运算符 Rational operator

一般来说,在调用operator<<()重载函数时,传递给它的是哪一个流,它返回的就应该是那个流的一个引用。

实例:左移操作符重载

  1 #include <iostream>
  2 #include <string>
  3 #include <math.h> 
  4 
  5 using namespace std;
  6 class Rational//定义基类
  7 {
  8 public:
  9     Rational(int num,int denom); //构造器 num = 分子,denom = 分母 
 10     
 11     Rational operator+(Rational rhs);// rhs == right hand side(右手边参数) 
 12     Rational operator-(Rational rhs);
 13     Rational operator*(Rational rhs);
 14     Rational operator/(Rational rhs);
 15     
 16 private:
 17     void normalize();//负责对分数的简化处理
 18     
 19     int numerator; //分子
 20     int denominator; //分母 
 21     
 22     friend ostream& operator<<(ostream& os,Rational f);//传递给它的是哪一个流,它返回的就是那个流的一个引用
 23 }; 
 24 
 25 Rational::Rational(int num,int denom)//构造函数实现 
 26 {
 27     numerator = num;
 28     denominator = denom;
 29     
 30     normalize(); 
 31 } 
 32 //normalize()对分数进行简化操作包括:
 33 //1.只允许分子为负数,如果分母为负数则把负数挪到分子部分,如1/-2==-1/2 
 34 //2.利用欧几里德算法(辗转求余原理)将分数进行简化:2/10 => 1/5 
 35 
 36 void Rational::normalize()
 37 {
 38     //确保分母为正
 39     if( denominator < 0) 
 40     {
 41         numerator = -numerator;
 42         denominator = -denominator;
 43     }
 44     //欧几里德算法 
 45     int a = abs(numerator);
 46     int b = abs(denominator);
 47     
 48     //求出最大公约数
 49     while(b>0)
 50     {
 51         int t = a % b;//取余 
 52         a = b;
 53         b = t;
 54     }
 55      
 56      //分子、分母分别除以最大公约数得到最简化分数
 57      numerator /= a;
 58      denominator /= a; 
 59 }
 60 //a   c   a*d   c*b   a*d + c*d
 61 //- + - = --- + --- = ----------
 62 //b   d   b*d   b*d      b*d
 63 Rational Rational::operator+(Rational rhs)//分数的加运算 
 64 {
 65     int a = numerator;
 66     int b = denominator;
 67     int c = rhs.numerator;
 68     int d = rhs.denominator;
 69     
 70     int e = a*b + c*d;
 71     int f = b*d;
 72     
 73     return Rational(e,f);
 74 }
 75 //a   c   a   -c
 76 //- - - = - + -- 
 77 //b   d   b   d 
 78 Rational Rational::operator-(Rational rhs)//分数的减运算 
 79 {
 80     rhs.numerator = -rhs.numerator; //被减数分子取负数 
 81     return operator+(rhs);
 82 }
 83 //a   c   a*c
 84 //- * - = --- 
 85 //b   d   b*d 
 86 Rational Rational::operator*(Rational rhs)//分数的乘运算
 87 {
 88     int a = numerator;
 89     int b = denominator;
 90     int c = rhs.numerator;
 91     int d = rhs.denominator;
 92     
 93     int e = a*c;
 94     int f = b*d;
 95     
 96     return Rational(e,f);
 97 }
 98 //a   c   a   d
 99 //- / - = - * - 
100 //b   d   b   c
101 Rational Rational::operator/(Rational rhs)//分数的除运算
102 {
103     //rhs的分子分母互换 
104     int t = rhs.numerator;
105     rhs.numerator = rhs.denominator;
106     rhs.denominator = t;
107     
108     return operator*(rhs);
109 }
110 
111 ostream& operator<<(ostream& os,Rational f);//函数声明 
112 
113 int main()
114 {
115     Rational f1(2,16);//定义f1对象,且传入(2,16)参数 
116     Rational f2(7,8);
117     
118     //测试有理数加法运算 
119     cout << f1 << " + " << f2 << " == " << (f1+f2) << "\n"; // 左移操作符<<已经被重载了 
120     
121     //测试有理数减法运算 
122      cout << f1 << " - " << f2 << " == " << (f1-f2) << "\n"; //<< f1中由于f1属于Rational类型,将自动转到打印分数形式输出 
123     
124     //测试有理数乘法运算 
125      cout << f1 << " * " << f2 << " == " << (f1*f2) << "\n";//<< "+"中由于<<后面参数是字符串,所以使用系统默认的打印 
126     
127     //测试有理数除法运算 
128     cout << f1 << " / " << f2 << " == " << (f1/f2) << "\n"; 
129     
130     return 0;
131 }
132 ostream& operator<<(ostream& os,Rational f)//并不属于Rational类,是一个独立的函数 
133 {
134     if(f.numerator % f.denominator == 0)
135     os << f.numerator / f.denominator;
136     else 
137     os << f.numerator << "/" << f.denominator;//打印分数 
138     return os; 
139 }

标签:denominator,int,rhs,左移,numerator,C++,运算符,Rational,operator
From: https://www.cnblogs.com/ybqjymy/p/17640552.html

相关文章

  • C++快速入门 第二十八讲:多继承(multiple inheritance)
    1多继承语法:23//助教类既继承于老师类,又继承于学生类4classAssistant:publicTeacher,publicStudent5{6};78当遇到的问题无法只用一个“是一个”关系来描述的时候,就是多继承出场的时候。例即是学生,又是人,还是助教。910#include<iostre......
  • C++快速入门 第三十讲:错误处理和调试
    程序出错可以分为两大类:编译时出错(complie-timeerror)和运行时错误(run-timeerror)suggest1:培养并保持一种编程风格suggest2:认真对待编译器给出的错误/警告信息suggest3:写代码三思而后行(先画流程图)suggest4:注意检查最基本的语法suggest5:把可能有问题的代码行注释suggest......
  • C++快速入门 第二十九讲:虚继承
    通过虚继承某个基类,就是在告诉编译器:从当前这个类再派生出来的子类只能拥有那个基类的一个实例。虚继承的语法:1classTeacher:virtualpublicPerson23{45}这样做的话便可以让Student和Teacher类都虚继承自Person类,编译器将确保从Student和Teacher类再派生出来的子......
  • C++快速入门 第三十一讲:错误处理与调试2
    让函数返回错误代码实例:范围限制1#include<iostream>2#include<climits>34usingnamespacestd;5classFactorial6{7public:8Factorial(unsignedshortnum);9unsignedlonggetFactorial();10boolinRange();1112private......
  • C++快速入门 第三十二讲:assert函数和捕获异常
    C语言和C++都有一个专门为调试而准备的工具函数---assert函数。这个函数是在assert.h库文件里定义的。实例1:assert函数应用1#include<cassert>2//assert()函数需要有一个参数,它将测试这个输入参数的真或者假状态3//如果为真Donothing4//如果为假Dosomething......
  • C++快速入门 第十八讲:访问控制
    访问控制:C++提供用来保护(保护意思是对谁可以调用某个方法和访问某一个属性加上一个限制)类里的方法和属性的手段实例1:访问级别应用1//级别允许谁来访问2//public任何代码3//protected这个类本身和它的子类4//private只有......
  • C++无法将类的成员函数赋值给一般的函数指针,解决方案
    遇到需要绑定回调函数的API接口。看了定义的函数指针,是静态的函数指针,将非静态的类成员函数赋值过去的时候,无法编译通过。将成员函数改成静态又得将整个类的内容都改成静态。这种情况下,可以构造匿名函数,引用this,这样可以在类中,将自己的成员函数赋值给需要的函数指针类型上:ser......
  • C++快速入门 第六讲:函数的重载
    函数重载:实质就是用同样的名字再定义一个有着不同参数类型及个数来实现不同操作的函数。实例1:改变同一函数的输入参数类型1#include<iostream>23voidconvertTemperature(doubletempIn,chartypeIn);4voidconvertTemperature(inttempIn,chartypeIn);5......
  • C++快速入门 第七讲:复杂的数据类型
    数组:可以把许多个同类型的值存储在同一变量名下实例1:输入的数据存储到数组中,并计算其和与平均值输出1#include<iostream>23usingnamespacestd;//使用作用域45intmain()6{7intarray[10];8inti;9intsum=0;10doubleaverage;......
  • C++快速入门 第八讲:复杂的数据类型——指针
    小知识:程序以文件的形式存储在硬盘,但它们却是在计算机的内存中运行对于变量可以通过变量名与地址两种方式进行索引,变量的地址在程序执行期间是不会发生变换的地址是计算机内存中的某个位置;指针是专门用来存放地址的特殊类型变量......