C++学习28 重载>>和<<(输入输出运算符)
在C++中,系统已经对左移运算符“<<”和右移运算符“>>”分别进行了重载,使其能够用于输入输出,但是输入输出的处理对象只能是系统内建的数据类型。系统重载这两个运算符是以系统类成员函数的形式进行的,因此cout<< var语句可以理解为:
cout.operator<<( var )
如果我们自己定义了一种新的数据类型,需要用输入输出运算符去处理,那么就要重载。本节以前面的 complex 类为例说明输入输出运算符的重载。
重载输入运算符>>
下面我们用全局函数的形式重载输入运算符,使它能够读入两个 double 类型的数据,并转换为一个复数,保存到复数对象中:
istream & operator>>(istream & in, complex & A){
in >> A.real >> A.imag;
return in;
}
istream 是输入流,cin 就是 istream 类的对象,后续会讲解。因为重载运算符函数需要用到 complex 类的 private 成员变量,为了方便,我们将这个函数声明为 complex 类的友元函数。声明形式如下:
friend istream & operator>>(istream & in , complex & a);
该函数可以按照如下方式使用:
complex c;
cin>> c;
当输入1.45 2.34↙后,这两个小数就分别成为 complex 对象 c 的实部和虚部了。cin>> c;这一语句其实可以理解为:
operator<<(cin , c);
在重载输入运算符时,采用引用的方式进行参数传递:输入的参数里面包含一个 istream 类的引用,返回值仍然为该引用。这样做的一个明显好处就是可以采用链式输入(也就是连续输入),如下所示:
complex c1, c2, c3;
cin>> c1 >> c2 >> c3;
重载输出运算符<<
同样的,我们也可以模仿上面的方式对输出运算符进行重载,让它能够输出复数。函数在类内部的声明如下:
rriend ostream &(ostream & out, complex & A);
全局函数的实现如下:
ostream & operator<<(ostream & out, complex & A){
out << A.real <<" + "<< A.imag <<" i ";
return out;
}
与 istream 相反,ostream 表示输出流,cout 就是 ostream 类的对象。为了能够直接访问 complex 类的私有成员变量,同样需要将这个函数声明为 complex 类的友元函数。由于采用了引用的方式进行参数传递,该输出运算符重载函数可以实现链式输出。
结合输入输出运算符的重载,重新实现 complex 类:
#include <iostream>
using namespace std;
class complex{
private:
double real; //复数的实部
double imag; //复数的虚部
public:
complex(): real(0.0), imag(0.0){ };
complex(double a, double b): real(a), imag(b){ };
friend complex operator+(const complex & A, const complex & B);
friend complex operator-(const complex & A, const complex & B);
friend complex operator*(const complex & A, const complex & B);
friend complex operator/(const complex & A, const complex & B);
friend istream & operator>>(istream & in, complex & A);
friend ostream & operator<<(ostream & out, complex & A);
};
//重载加法运算符
complex operator+(const complex & A, const complex &B){
complex C;
C.real = A.real + B.real;
C.imag = A.imag + B.imag;
return C;
}
//重载减法运算符
complex operator-(const complex & A, const complex &B){
complex C;
C.real = A.real - B.real;
C.imag = A.imag - B.imag;
return C;
}
//重载乘法运算符
complex operator*(const complex & A, const complex &B){
complex C;
C.real = A.real * B.real - A.imag * B.imag;
C.imag = A.imag * B.real + A.real * B.imag;
return C;
}
//重载除法运算符
complex operator/(const complex & A, const complex & B){
complex C;
double square = A.real * A.real + A.imag * A.imag;
C.real = (A.real * B.real + A.imag * B.imag)/square;
C.imag = (A.imag * B.real - A.real * B.imag)/square;
return C;
}
//重载输入运算符
istream & operator>>(istream & in, complex & A){
in >> A.real >> A.imag;
return in;
}
//重载输出运算符
ostream & operator<<(ostream & out, complex & A){
out << A.real <<" + "<< A.imag <<" i ";;
return out;
}
int main(){
complex c1, c2, c3;
cin>>c1>>c2; c3 = c1 + c2;
cout<<"c1 + c2 = "<<c3<<endl;
c3 = c1 - c2;
cout<<"c1 - c2 = "<<c3<<endl;
c3 = c1 * c2;
cout<<"c1 * c2 = "<<c3<<endl;
c3 = c1 / c2;
cout<<"c1 / c2 = "<<c3<<endl;
return ;
}
在本例中,我们均采用全局函数的形式进行运算符重载,这样在输入输出时方便了不少。
C++学习28 重载>>和<<(输入输出运算符)的更多相关文章
- C++学习29 重载[](下标运算符)
前面已经提到,下标操作符[]必须以类的成员函数的形式进行重载.在类中的声明格式如下: 返回值类型 & operator[] (参数) 或 const 返回值类型 & operator[ ...
- C++运算符重载——输入/输出运算符
为了与IO标准库一致,重载输入输出运算符函数的第一个行参应该是流的引用,第二个行参是对象的引用. 如果重载为类的成员函数,第一个行参应该是对象的引用,第二个行参是流的引用. 使用方式是 ClassOb ...
- # c++运算符重载之 前置++, 后置++, 负号运算符, 类型转换函数, 以及输入输出运算符
c++运算符重载之 前置++, 后置++, 负号运算符, 类型转换函数, 以及输入输出运算符 标签(空格分隔): c++ 前言 我在c++学习的过程中, 对这几个不太常见的运算符重载不太会写.出现了很 ...
- C++重载>>和<<(输入输出运算符)
在C++中,标准库本身已经对左移运算符<<和右移运算符>>分别进行了重载,使其能够用于不同数据的输入输出,但是输入输出的对象只能是 C++ 内置的数据类型(例如 bool.in ...
- C++重载流插入运算符和流提取运算符【转】
C++的流插入运算符“<<”和流提取运算符“>>”是C++在类库中提供的,所有C++编译系统都在类库中提供输入流类istream和输出流类ostream.cin和cout分别是 ...
- 我的MYSQL学习心得(五) 运算符
我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...
- C++学习之文件的输入输出
C++学习之文件的输入输出 一.文件的打开与关闭 1.输出数据到文件 文件的操作需要包含fstream头文件,文件的操作对象为ifstream,ofstrea ...
- 催希凡javaweb 学习28天
看到这样的博客,自己也在看传智播客的视频,收藏一下 催希凡javaweb 学习28天 http://www.cnblogs.com/Prozhu/category/824899.html
- operator 重载内置运算符
operator 关键字来重载内置运算符,或提供类或结构声明中的用户定义转换.它可以定义不同类型之间采用何种转化方式和转化的结果. operator用于定义类型转化时可采用2种方式,隐式转换(impl ...
随机推荐
- easyUI之message
message组件,依赖于window组件.progressbar组件两个面板. 它有几个不同的显示风格,与vb中的msgbox相对应,有alert.progrss.confirm.prompt等形式 ...
- risc与cisc
RISC(精简指令集计算机)和CISC(复杂指令集计算机)是当前CPU的两种架构.它们的区别在于不同的CPU设计理念和方法. 早期的CPU全部是CISC架构,它的设计目的是要用最少的机器语言指令来完成 ...
- ASP.Net:Table类的使用
在做Asp.Net的时候,很多情况下数据的绑定都是使用GridView或者我之前提到的ListView,但是这两个适合用于数据的绑定,而有些时候,数据需要在后台进行处理,例如数据据内地某一条数据的特殊 ...
- 【转】JS跨域(ajax跨域、iframe跨域)解决方法及原理详解(jsonp)
这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...
- Apache 性能优化
有一个升级服务器,这几天一直访问的比较慢.导致部分用户升级不了.看了一下服务器的负载,发现 CPU和内存占用的都不是很高,可能是Apache配置不当造成的,一番搜索,找到了MPM的配置,提速很明显哦 ...
- mysql sys table
本文详细地介绍了MySQL 5.7新引入的sys schema.首先,本文概要地介绍了sys schema的作用和定位:其次,分别介绍了sys schema中的视图.函数和存储过程:接下来,通过两个例 ...
- 【java】 java 实现mysql备份
使用java实现mysql的备份: public class MySQLBackUp { /** * Java代码实现MySQL数据库导出 * * @author GaoHuanjie * @para ...
- c# 中的多线程和异步
前言: 1.异步和多线程有区别吗? 答案:多线程可以说是实现异步的一种方法方法,两者的共同目的:使主线程保持对用户操作的实时响应,如点击.拖拽.输入字符等.使主程序看起来实时都保持着等待用户响应的状态 ...
- [转] matlab figure最大化
http://blog.163.com/yinhexiwen@126/blog/static/6404826620122942057214/ % figure 窗口最大化,坐标轴也随着窗口变大而相应变 ...
- C#实现监控网络流量
本文转载自:http://blog.csdn.net/zhanjianshinian/article/details/8177851 public partial class NetJiankongF ...