首先思考以下几个问题:

1.什么是运算符重载?

2.为什么要重载运算符,它有什么用?

3.可以重载哪些运算符?

4.重载运算符有哪些规则?

一、基本概念

我们在程序中使用各种操作符,比如加(+)、赋值(=)等等。运算符重载可以重新赋予操作符的含义,举个栗子,对于加号操作符,一般都是将两个数进行相加,而不能将两个自定义类的对象相加,但是通过运算符重载可以这么做。

重载运算符是具有特殊名称的函数,函数具有哪些特征呢?1.函数名称;2.返回类型;3.参数列表;4.函数体。

1.名称的写法是保留字operator后接需定义的操作符号;

2.返回类型后面再说;

3.参数:参数数目与该运算符作用的运算对象数目相同,但如果是作为一个类的成员函数,(显式)参数数目比运算对象总数少一个(因为有一个隐含的this形参)。

1.哪些运算符可以被重载

只知道哪些可以、哪些不可以被重载,没有太大意义。

2.重载运算符怎么调用

如果是非成员运算符函数:

star1 + star2;			//普通表达式
operator+(star1, star2); //等价的函数调用

如果是成员运算符函数:

star1 += star2;			//基于调用的表达式
star1.operator+=(star2); //等价的调用

  

二、为什么要重载运算符

大多数人平时很少用到运算符重载,因为运算符重载的功能一般都可以通过直接写一个普通函数实现。但运算符重载可以使的程序更加“优美”,在有的情形下,可以使我们更容易使用标准库容器和算法。

三、输入、输出运算符

我们现在有一个类SuperStar,代表超级巨星,它有一个成员变量代表巨星的姓名。

现在我们的任务是输入、输出巨星的名字。

class SuperStar
{
public:
SuperStar();
~SuperStar();
private:
string m_strName; //姓名
};

1.输出运算符<<

输出运算符第一个参数是ostream的引用,第二个参数是一个常量的引用。

ostream &operator<<(ostream &os, const SuperStar &star)
{
os << star.m_strName;
return os;
}

2.输入运算符>>

输入运算符第一个参数是将要读取的流的引用,第二个参数是将要读入到的对象的引用。

istream &operator>>(istream &is, SuperStar &star)
{
if (is)//检查是否输入成功
is >> star.m_strName;
else
star = SuperStar();
return is;
}

值得注意的是参数为什么是引用,还有参数为什么是/不是常量。

输入输出运算符必须是非成员函数,但是IO运算符需要读写类的非公有成员,所以一般被声明为友元。

friend istream& operator>>(istream &, SuperStar &);
friend ostream& operator<<(ostream &, const SuperStar &);

  

四、算术和关系运算符

1.相等运算符==

假如现在有2个明星,一个叫饭冰冰,另一个叫凤咀

 VS 

我们根据名字来判断她们是不是一样的(这样做也许有失合理,请不要太在意细节)

bool operator==(const SuperStar &star1, const SuperStar &star2)
{
return star1.m_strName == star2.m_strName;
} bool operator!=(const SuperStar &star1, const SuperStar &star2)
{
return !(star1 == star2);
}

让我们试一下效果:

SuperStar star1;
SuperStar star2;
cout << "亲爱的经纪人,请创造1号女星:";
cin >> star1;
cout << "请创造2号女星:";
cin >> star2;
cout << "1号" << star1 << ";2号" << star2 << endl;;
cout << "她们" << ((star1 == star2) ? "相同" : "不相同") << endl;

2.算术运算符+

SuperStar operator+(const SuperStar &star1, const SuperStar &star2)
{
SuperStar star3 = star1;
star3 += star2;
return star3;
}

上面使用了复合赋值运算符+=,这一点后面会将。(note:如果类同时定义了算术运算符和复合赋值运算符,通常应使用复合赋值运算符来实现算术运算符)

五、赋值运算符

1.赋值运算符=

凤咀对自己名字不满意,于是想改名叫饭冰冰。

:“我叫饭冰冰,你爱我吗?”

SuperStar & SuperStar::operator=(const SuperStar &star)
{
if (this != &star)
{
m_strName = star.m_strName;
}
return *this;
}

这里要注意赋值给自己的情况,有一本叫《C++沉思录》的书里面有深入的讲解。

赋值运算符必须定义为成员函数。

2.复合赋值运算符+=

凤咀想:直接叫别人的名字不太好,把她名字加在我后面吧!

:“我叫凤咀饭冰冰,你还爱我吗?”

SuperStar & SuperStar::operator+=(const SuperStar &star)
{
m_strName += star.m_strName;
return *this;
}

复合赋值运算符不非得是类的成员,不过倾向于把所有赋值运算都定义在类内部。

六、递增和递减运算符

1.前置递增/递减运算符

首先在类中定义它们:

SuperStar &operator++();
SuperStar &operator--();

具体实现:

SuperStar & SuperStar::operator++()
{
check();
++curr;
return *this;
}
SuperStar & SuperStar::operator--()
{
--curr;
check();
return *this;
}

注意其中检查是否越界,如果越界,将会抛出out_of_range异常。

2.后置递增/递减运算符

为了区分前置与后置,后置版本接受一个额外的(不使用的)int类型的参数。

SuperStar & SuperStar::operator++(int)
{
SuperStar ret = *this;
++*this;
return ret;
}
SuperStar & SuperStar::operator--(int)
{
SuperStar ret = *this;
--*this;
return ret;
}

后置运算符调用各自的前置版本来完成实际的工作。

以上只是运算符重载的一小部分,想认识更多还需要多看书多思考。

C++中的运算符重载的更多相关文章

  1. C++中的运算符重载注意事项

    1.C++中的运算符重载的方式有三种: a.类成员函数重载 b.友元函数重载 c.普通函数重载 注意: a.我们主要使用的方式主要是用:类成员函数和友元函数来实现运算符的重载. b.其实用普通函数理论 ...

  2. c++中的运算符重载operator2(翁恺c++公开课[31-33]学习笔记)

    上一篇operator1中,大概说了下重载的基本用法,接下来对c++中常见的可重载运算符归一下类,说一下它们的返回值,讨论下较为复杂的运算符重载上的坑

  3. c++中的运算符重载operator1(翁恺c++公开课[30]学习笔记)

    运算符重载规则: 只有已经存在的运算符才能被重载,不能自己制造一个c++中没有的运算符进行重载 重载可以在类或枚举类型内进行,也可以是全局函数,但int.float这种已有的类型内是不被允许的 不能二 ...

  4. C++走向远洋——50(Time类中的运算符重载、一目,二目比较运算符、二目赋值运算符、二目加减法运算符)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  5. C++走向远洋——49(项目一2、复数类中的运算符重载、类的友元函数)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  6. C++走向远洋——48(项目一1、复数类中的运算符重载、类的成员函数)

    */ * Copyright (c) 2016,烟台大学计算机与控制工程学院 * All rights reserved. * 文件名:text.cpp * 作者:常轩 * 微信公众号:Worldhe ...

  7. C++中的运算符重载练习题

    1.RMB类 要求: 定义一个RMB类 Money,包含元.角.分三个数据成员,友元函数重载运算符‘+’(加)   和 ‘-’(减),实现货币的加减运算     例如:    请输入元.角 分:    ...

  8. 在Lua中进行运算符重载

    在C++里面运算符是可以重载的,这一点也是C++比较方便的一个地方.在Lua中其实也是可以模拟出运算符的重载的. 在Lua中table中元素的运算都是和一个叫做元表有关的,在一个table型的变量上都 ...

  9. Python 中的运算符重载

    本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,如有问题请及时联系我们以作处理 一种运算符对于不同类型的对象,有不同的使用方式.例如, + 用于整型对象,表示两个数相加:用于字符串 ...

随机推荐

  1. [HTML5] 飞龙天惊-HTML5学习系列

    飞龙天惊 cnblog URL:http://www.cnblogs.com/fly_dragon/ Html5 学习系列(一)认识HTML5 http://www.cnblogs.com/fly_d ...

  2. CSS Hack(转)

    做前端多年,虽然不是经常需要hack,但是我们经常会遇到各浏览器表现不一致的情况.基于此,某些情况我们会极不情愿的使用这个不太友好的方式来达到大家要求的页面表现.我个人是不太推荐使用hack的,要知道 ...

  3. ABAP内表(internal table)有关的系统变量

    SY-TABIX – 内表当前行的索引号.SY-TABIX 的值可以被以下命令修改,但是只适用于索引表(index table).对于哈希表(Hashed table),这个系统变量的值为空或0. A ...

  4. SharePoint 新特性及安装需知

    以下内容转自Kaneboy 大牛,但我在安装正式版的过程中发现一些问题,主要是.net 版本的问题,弄了我一个晚上,我在下面标出来了.我的安装环境是Windows server 2012 R2 关于详 ...

  5. How to upgrade workflow assembly in MOSS 2007

    This problem generally start when you are having an existing custom workflow and there are instances ...

  6. IOS 杂笔-3 (property参数)

    (1)内存管理相关参数 Retain:对对象release旧值,retain新值(适用于OC对象类型) Assign:直接赋值(默认,适用于非oc对象类型) Copy:release旧值,copy新值 ...

  7. 招聘一个靠谱的 iOS程序员

    一个靠谱的简历 简历非常能反映一个人的性格和水平,相比于你在学校获得多少奖项,工作经历.项目经 历.熟悉的技术等更加关键,如果还有博客和一些 Github 上的项目,好感度++,但记得在去面试前收拾下 ...

  8. android 音乐播放器简单实现

    package com.zhangbz.musicplayer; import java.io.File; import android.app.Activity; import android.me ...

  9. C# 3个线程A B C 依次打印123123123..

    C#经典面试题: 有3个线程,A线程打印1,B线程打印2,C线程打印3,请用程序实现依次打印123123123... class Program { static void Main(string[] ...

  10. paas架构之docker——安装

    1. 概要 本文描述docker的安装 参考官方文档:https://docs.docker.com/engine/installation/linux/ubuntulinux/ 安装操作系统: Ub ...