在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 重载>>和<<(输入输出运算符)的更多相关文章

  1. C++学习29 重载[](下标运算符)

    前面已经提到,下标操作符[]必须以类的成员函数的形式进行重载.在类中的声明格式如下: 返回值类型 & operator[] (参数) 或 const 返回值类型 & operator[ ...

  2. C++运算符重载——输入/输出运算符

    为了与IO标准库一致,重载输入输出运算符函数的第一个行参应该是流的引用,第二个行参是对象的引用. 如果重载为类的成员函数,第一个行参应该是对象的引用,第二个行参是流的引用. 使用方式是 ClassOb ...

  3. # c++运算符重载之 前置++, 后置++, 负号运算符, 类型转换函数, 以及输入输出运算符

    c++运算符重载之 前置++, 后置++, 负号运算符, 类型转换函数, 以及输入输出运算符 标签(空格分隔): c++ 前言 我在c++学习的过程中, 对这几个不太常见的运算符重载不太会写.出现了很 ...

  4. C++重载>>和<<(输入输出运算符)

    在C++中,标准库本身已经对左移运算符<<和右移运算符>>分别进行了重载,使其能够用于不同数据的输入输出,但是输入输出的对象只能是 C++ 内置的数据类型(例如 bool.in ...

  5. C++重载流插入运算符和流提取运算符【转】

    C++的流插入运算符“<<”和流提取运算符“>>”是C++在类库中提供的,所有C++编译系统都在类库中提供输入流类istream和输出流类ostream.cin和cout分别是 ...

  6. 我的MYSQL学习心得(五) 运算符

    我的MYSQL学习心得(五) 运算符 我的MYSQL学习心得(一) 简单语法 我的MYSQL学习心得(二) 数据类型宽度 我的MYSQL学习心得(三) 查看字段长度 我的MYSQL学习心得(四) 数据 ...

  7. C++学习之文件的输入输出

    C++学习之文件的输入输出        一.文件的打开与关闭        1.输出数据到文件        文件的操作需要包含fstream头文件,文件的操作对象为ifstream,ofstrea ...

  8. 催希凡javaweb 学习28天

    看到这样的博客,自己也在看传智播客的视频,收藏一下 催希凡javaweb 学习28天 http://www.cnblogs.com/Prozhu/category/824899.html

  9. operator 重载内置运算符

    operator 关键字来重载内置运算符,或提供类或结构声明中的用户定义转换.它可以定义不同类型之间采用何种转化方式和转化的结果. operator用于定义类型转化时可采用2种方式,隐式转换(impl ...

随机推荐

  1. Q5: Remove Duplicates from Sorted Array

    问题描述: Given a sorted array, remove the duplicates in place such that each element appear only once a ...

  2. 【转】ASP.NET中服务器控件Table动态生成表格及其属性介绍

    下文所有内容转自开源中国:http://www.oschina.net/question/565065_86453#tags_nav ================================= ...

  3. kubernetes centos 安装

    1.  安装       yum install -y  etcd  kubernetes   2.  配置         docker             /etc/sysconfig/doc ...

  4. MySQL数据库update更新子查询

    比如: ? 1 2 3 4 UPDATE test.tb_vobile a set a.name = '111 ' WHERE a.id = (select max(id) id from test. ...

  5. dubbo远程调试运行

    缺包问题: maven配置或则下载 http://central.maven.org/maven2/org/mortbay/jetty/jetty/7.0.0.pre5/jetty-7.0.0.pre ...

  6. nginx基于域名的虚拟主机 反向代理配置实例

    vi /etc/nginx/conf.d/safeadmin.xxx.com.conf: server { listen 80; server_name safeadmin.xxxx.com; loc ...

  7. Android 中Fragment使用

    Android 中Fragment使用 public class MainActivity extends Activity { public static String[] array = { &q ...

  8. Android MVC模式

    Android MVC模式 下面是我对Android MVC模式的理解 Model 模型层 包括实体模型层,存放程序中调用的实体. 业务模型层,存放程序中调用的业务逻辑.   View 显示层  An ...

  9. 【控件扩展】带圆角、边框、渐变的panel

    下载地址:  http://files.cnblogs.com/chengulv/custompanel_demo.zip using System; namespace LC.Fun { /// & ...

  10. OC-设计模式KVC+KVO定义及使用

    一.KVC Key-Value-Coding 键值编码(KVC:是一种存取值的方式,通过key存value 或者通过key获取value key从哪里来的呢? key 把对象里面的属性名.变量名当作了 ...