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 ...
随机推荐
- mysql提权笔记
最近小菜遇到mysql提权,总是会搞错,就记记笔记吧!以后方便用 先说手工吧! mysql<5.0,导出路径随意:5.0<=mysql<5.1,则需要导出至目标服务器的系统目录(如: ...
- 007. 自定义ListBox的item的宽高, 字体居中
/// <summary> /// 自定义ListBox的item的宽高, 字体居中 /// </summary> /// <param name="sende ...
- PHP5.3以上版本没有libmysql.dll,以及由此带来的困扰
有朋友下载了PHP5.3,PHP5.4版本想加载mysql支持的时候发现没有libmysql.dll文件,无法完成mysql配置,其实PHP5.3版本开始,使用mysqlnd库,不再使用libmysq ...
- Dubbo与Zookeeper、SpringMVC整合和使用(负载均衡、容错)转
互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的.现在核心业务抽取出来,作为独立的服务,使 ...
- ImageView及其子类
ImageView及其子类 (1)ImageView继承自View组件,任何Drawable对象都可以用ImageView来显示,ImageView派生出来了ImageButton.ZoomButto ...
- nginx linux 下开机自动启动
这里使用的是编写shell脚本的方式来处理 vi /etc/init.d/nginx (输入下面的代码) #!/bin/bash# nginx Startup script for the Ngin ...
- ABP系列文章总目录:
转自:http://www.cnblogs.com/mienreal/p/4528470.html 1.ABP总体介绍 2.ASP.NET Boilerplate入门 3.ABP分层架构 4.ABP模 ...
- php生成二维码可以有以下几种方式
1.google开放api $urlToEncode="http://bbs.lewanchina.com"; generateQRfromGoogle($urlToEncode) ...
- 【jmeter】元件的作用域与执行顺序
1.元件的作用域 JMeter中共有8类可被执行的元件(测试计划与线程组不属于元件),这些元件中,取样器是典型的不与其它元件发生交互作用的元件,逻辑控制器只对其子节点的取样器有效,而其它元件(conf ...
- LintCode "Expression Tree Build"
Lesson learnt: for any calculator problems, keep 2 stacks: 1 for operators and 1 for operands. class ...