首先思考以下几个问题:

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. 通过GPS数据反向地理信息编码, 得到当前位置信息

    检查可用性 这属于基础知识, 不赘述, 总的来说,你的设备的支持要打开, 添加CoreLocation的framework, 引用头文件, 添加委托,然后, 好的实践是在使用前编程检查相关可用性: - ...

  2. NPOI导出数据到Excel

    NPOI导出数据到Excel   前言 Asp.net操作Excel已经是老生长谈的事情了,可下面我说的这个NPOI操作Excel,应该是最好的方案了,没有之一,使用NPOI能够帮助开发者在没有安装微 ...

  3. java多线程系列3-线程同步

    如果一个资源被多个线程同时访问,可能会遭到破坏,这篇文章介绍java线程同步来解决这类问题 引入问题 某电影院目前正在上映贺岁大片,共有100张票,而它有3个售票窗口售票,请设计一个程序模拟该电影院售 ...

  4. C语言中的指针和内存泄漏

    引言 对于任何使用C语言的人,如果问他们C语言的最大烦恼是什么,其中许多人可能会回答说是指针和内存泄漏.这些的确是消耗了开发人员大多数调试时间的事项.指针和内存泄漏对某些开发人员来说似乎令人畏惧,但是 ...

  5. 【读书笔记】iOS-Tagged Pointer对象-注意事项

    一,2013年9月,苹果推出了iPhone5s,与此同时,iPhone5s配备了首个采用64位架构的A7双核处理器,为了节省内存和提高执行效率,苹果提出了Tagged Pointer的概念. 对于64 ...

  6. 安卓第十天笔记-fragment

    安卓第十天笔记-fragment Fragment(片段) 一.Fragment简介 *Fragment是3.0引入的API,主要为了解决平板,大屏幕手机显示问题 *Fragment代表了Activi ...

  7. mac 下安装android studio(转)

    1)下载最新jdk8,下载android studio 2)安装jdk8,双击jdk8的安装包,将jdk8的安装包拖到Application,可能会出现这种问题:要求Mac OS X10.7.3或更高 ...

  8. Erlang数据类型的表示和实现(5)——binary

    binary 是 Erlang 中一个具有特色的数据结构,用于处理大块的“原始的”字节块.如果没有 binary 这种数据类型,在 Erlang 中处理字节流的话可能还需要像列表或元组这样的数据结构. ...

  9. Effective Java 44 Write doc comments for all exposed API elements

    Principle You must precede every exported class, interface, constructor, method, and field declarati ...

  10. Force.com平台基础

    当我开始写这篇博客的时候,<Force.com Platform Fundamentals>的PDF版本我还没看到十分之一.由于PDF全部是英文的,所以我看起来比较吃力.我尝试过边看边做笔 ...