上一节主要讲解了C++里运算符重载函数,在看了单目运算符(++)重载的示例后,也许有些朋友会问这样的问题。++自增运算符在C或C++中既可以放在操作数之前,也可以放在操作数之后,但是前置和后置的作用又是完全不同的(q前置运算符:先加1,再赋值;后置运算符:先赋值,再加1)。那么要怎么重载它们,才可以有效的区分开来呢?今天我就来说说C++中是怎么处理前置运算符和后置运算符的重载的。以及介绍一下插入运算符(>>)和提取运算符(<<)的重载。

  1.在C++里编译器是根据运算符重载函数参数表里是否插入关键字int来区分前置还是后置运算。比如:

 1 #include "stdafx.h"
2 #include <iostream>
3
4 class TDPoint//三维坐标
5 {
6 private:
7 int x;
8 int y;
9 int z;
10 public:
11 TDPoint(int x=0,int y=0,int z=0)
12 {
13 this->x=x;
14 this->y=y;
15 this->z=z;
16 }
17 TDPoint operator++();//成员函数重载前置运算符++
18 TDPoint operator++(int);//成员函数重载后置运算符++
19 friend TDPoint operator++(TDPoint& point);//友元函数重载前置运算符++
20 friend TDPoint operator++(TDPoint& point,int);//友元函数重载后置运算符++
21 void showPoint();
22 };
23
24 TDPoint TDPoint::operator++()
25 {
26 ++this->x;
27 ++this->y;
28 ++this->z;
29 return*this;//返回自增后的对象
30 }
31
32 TDPoint TDPoint::operator++(int)
33 {
34 TDPoint point(*this);
35 this->x++;
36 this->y++;
37 this->z++;
38 return point;//返回自增前的对象
39 }
40
41 TDPoint operator++(TDPoint& point)
42 {
43 ++point.x;
44 ++point.y;
45 ++point.z;
46 return point;//返回自增后的对象
47 }
48
49 TDPoint operator++(TDPoint& point,int)
50 {
51 TDPoint point1(point);
52 point.x++;
53 point.y++;
54 point.z++;
55 return point1;//返回自增前的对象
56 }
57
58 void TDPoint::showPoint()
59 {
60 std::cout<<"("<<x<<","<<y<<","<<z<<")"<<std::endl;
61 }
62
63 int main()
64 {
65 TDPoint point(1,1,1);
66 point.operator++();//或++point
67 point.showPoint();//前置++运算结果
68
69 point=point.operator++(0);//或point=point++
70 point.showPoint();//后置++运算结果
71
72 operator++(point);//或++point;
73 point.showPoint();//前置++运算结果
74
75 point=operator++(point,0);//或point=point++;
76 point.showPoint();//后置++运算结果
77
78 return0;
79 }

结果:

从示例代码里可以清楚的看出,后置运算符重载函数比前置运算符重载函数多了一个int类型的参数,这个参数只是为了区别前置和后置运算符,此外没有任何作用。所以在调用后置运算符重载函数时,int类型的实参可以取任意值。

  2.在C++中,操作符"<<"和">>"被定义为左位移运算符和右位移运算符。由于在iostream头文件中对它们进行了重载,使得它们可以用基本数据的输出和输入。

#include "stdafx.h"
#include <iostream> int main()
{
int a=10;
std::cout<<"a="<<a<<std::endl;//运算符"<<"重载后用于输出
a=a>>2;//右移运算符
std::cout<<"右移2位:a="<<a<<std::endl; std::cout<<"请输入一个整数a:";
std::cin>>a;//运算符">>"重载后用于输入
a=a<<2;//左移运算符
std::cout<<"左移2位:a="<<a<<std::endl; return0;
}

结果:

插入运算符"<<"是双目运算符,左操作数为输出流类ostream的对象,右操作数为系统预定义的基本类型数据。头文件iostrem对其重载的函数原型为ostream& operator<<(ostream& ,类型名);类型名就是指基本类型数据。但如果要输出用户自定义的类型数据的话,就需要重载操作符"<<",因为该操作符的左操作数一定为ostream类的对象,所以插入运算符"<<"只能是类的友元函数或普通函数,不能是其他类的成员函数。一般定义格式:

  ostream& operator<<(ostream& ,自定义类名&);

提取运算符">>"也是如此,左操作数为istream类的对象,右操作数为基本类型数据。头文件iostrem对其重载的函数原型为istream& operator>>(istream& ,类型名);提取运算符也不能作为其他类的成员函数,可以是友元函数或普通函数。它的一般定义格式为:

  istream& operator>>(istream& ,自定义类名&);

我还是用上一节用的Complex类(复数类)来举例:

#include "stdafx.h"
#include <iostream> class Complex //复数类
{
private://私有
double real;//实数
double imag;//虚数
public:
Complex(double real=0,double imag=0)
{
this->real=real;
this->imag=imag;
}
friend std::ostream&operator<<(std::ostream& o,Complex& com);//友元函数重载提取运算符"<<"
friend std::istream&operator>>(std::istream& i,Complex& com);//友元函数重载插入运算符">>"
}; std::ostream&operator<<(std::ostream& o,Complex& com)
{
std::cout<<"输入的复数:";
o<<com.real;
if(com.imag>0)
o<<"+";
if(com.imag!=0)
o<<com.imag<<"i"<<std::endl;
return o;
} std::istream&operator>>(std::istream& i,Complex& com)
{
std::cout<<"请输入一个复数:"<<std::endl;
std::cout<<"real(实数):";
i>>com.real;
std::cout<<"imag(虚数):";
i>>com.imag;
return i;
} int main()
{ Complex com;
std::cin>>com;
std::cout<<com; return0;
}

结果:

出处:http://www.cnblogs.com/CaiNiaoZJ/archive/2011/08/13/2137033.html

[转]C++之运算符重载(2)的更多相关文章

  1. C++ 运算符重载时,将运算符两边对象交换问题.

    在C++进行运算符重载时, 一般来讲,运算符两边的对象的顺序是不能交换的. 比如下面的例子: #include <iostream> using namespace std; class ...

  2. C#高级编程笔记2016年10月12日 运算符重载

    1.运算符重载:运算符重重载的关键是在对象上不能总是只调用方法或属性,有时还需要做一些其他工作,例如,对数值进行相加.相乘或逻辑操作等.例如,语句if(a==b).对于类,这个语句在默认状态下会比较引 ...

  3. C++运算符重载

    C++运算符重载 基本知识 重载的运算符是具有特殊名字的函数,他们的名字由关键字operator和其后要定义的运算符号共同组成. 运算符可以重载为成员函数和非成员函数.当一个重载的运算符是成员函数时, ...

  4. 标准C++之运算符重载和虚表指针

    1 -> *运算符重载 //autoptr.cpp     #include<iostream> #include<string> using namespace std ...

  5. python运算符重载

    python运算符重载就是在解释器使用对象内置操作前,拦截该操作,使用自己写的重载方法. 重载方法:__init__为构造函数,__sub__为减法表达式 class Number: def __in ...

  6. PoEduo - C++阶段班【Po学校】-Lesson03-5_运算符重载- 第7天

    PoEduo - Lesson03-5_运算符重载- 第7天 复习前面的知识点 空类会自动生成哪些默认函数 6个默认函数    1  构造  2  析构   3  赋值  4 拷贝构造  5 oper ...

  7. 不可或缺 Windows Native (24) - C++: 运算符重载, 自定义类型转换

    [源码下载] 不可或缺 Windows Native (24) - C++: 运算符重载, 自定义类型转换 作者:webabcd 介绍不可或缺 Windows Native 之 C++ 运算符重载 自 ...

  8. 我的c++学习(8)运算符重载和友元

    运算符的重载,实际是一种特殊的函数重载,必须定义一个函数,并告诉C++编译器,当遇到该运算符时就调用此函数来行使运算符功能.这个函数叫做运算符重载函数(常为类的成员函数). 方法与解释 ◆ 1.定义运 ...

  9. c/c++面试题(6)运算符重载详解

    1.操作符函数: 在特定条件下,编译器有能力把一个由操作数和操作符共同组成的表达式,解释为对 一个全局或成员函数的调用,该全局或成员函数被称为操作符函数.该全局或成员函数 被称为操作符函数.通过定义操 ...

  10. 实验12:Problem H: 整型数组运算符重载

    Home Web Board ProblemSet Standing Status Statistics   Problem H: 整型数组运算符重载 Problem H: 整型数组运算符重载 Tim ...

随机推荐

  1. s12-day01-work02 python多级菜单展示

    README # README.md # day001-work-2 @南非波波 功能实现:多级菜单展示 流程图: ![](http://i.imgur.com/VTPPhZU.jpg) 程序实现: ...

  2. Kafka/Metaq设计思想学习笔记

    http://my.oschina.net/geecoodeer/blog/194829

  3. 9-1 A Spy in the Metro uva1025 城市里的间谍 (DP)

    非常有价值的dp题目  也是我做的第一题dp    真的效率好高 题意:某城市的地铁是线性的 有n个车站 从左到右编号为1-n  有m1辆列车从第一站开始往右开 还有m2辆列车从第n站开始往左开  在 ...

  4. Android消息总线的演进之路:用LiveDataBus替代RxBus、EventBus

    背景 对于Android系统来说,消息传递是最基本的组件,每一个App内的不同页面,不同组件都在进行消息传递.消息传递既可以用于Android四大组件之间的通信,也可用于异步线程和主线程之间的通信.对 ...

  5. ssm框架常见问题

    搭建SSM框架时,总是遇到这样那样的问题,有的一眼就能看出来,有的需要经验的积累.现将自己搭建SSM框架时遇到的典型问题总结如下: 一.Struts2框架下的action中无法使用@Autowired ...

  6. 解决springboot项目中@Value注解参数值为null的问题

    1.错误场景: springboot项目中在.properties文件(.yml)文件中配置了属性值,在Bean中使用@Value注解引入该属性,Bean的构造器中使用该属性进行初始化,此时有可能会出 ...

  7. 某谷 P5153 简单的函数

    题面在这里 个人感觉这个题可以被打表随便艹过,当然我不是这么做的... 虽然n可达10^18,但随便分析一下就可以发现f(n)是极小的,因为f(n)一步就可以跳到f(前100),不信你算一下前100个 ...

  8. 关于多重嵌套的JSON数据解析

    最近项目中需要封装一套复杂的数据模型返回给前端,大致就是一个用户会有多笔订单,每个订单下可能会有多笔保单, 大致的数据模型如下: 为了方面描述,先看一下一个用户下有一条订单,一条订单下有一个保险订单的 ...

  9. Hibernate与MyBatis的对比总结

    最近做了一个Hibernate与MyBatis的对比总结,希望大家指出不对之处. 第一章     Hibernate与MyBatis Hibernate 是当前最流行的O/R mapping框架,它出 ...

  10. [Linux] tmux 终端复用命令行工具

    tmux 终端复用命令行工具 tmux 是一款终端复用命令行工具,通常用于 Terminal 的窗口管理.可以在终端软件重启后通过命令行恢复上次的 session. 安装运行 macOS 上使用 Ho ...