运算符重载

运算符重载使自定义类的对象能像内置类型的变量一样使用内置的运算符,扩充运算符的功能,增强了C++ 语言的可扩充性。

注意点:

  • 不是所有的运算符都能重载
  • 重载不能改变运算符的优先级和结合性
  • 重载不能改变运算符的操作数个数
  • 不能创建新的运算符

运算符重载的方法

C++中规定,重载函数名为operator@,其中,@为要重载的运算符。如要重载+运算符,该重载函数名为operator+

函数原型

运算符的重载不能改变运算符的运算对象数。因此,重载函数的形式参数个数(包括成员函数的隐式指针this)与运算符的运算对象数相同 。
运算符重载可以重载成成员函数也可以重载成全局函数实现。重载成全局函数时,最好把此函数设为友员函数。
如果作为类的成员函数,它的形式参数个数比运算符的运算对象数少1。这是因为成员函数有一个隐含的参数this。在C++中,把隐含参数this作为运算符的第一个参数。
所以当把一个一元运算符重载成成员函数时,该函数没有形式参数。把一个二元运算符重载成成员函数时,该函数只有一个形式参数,就是右操作数,当前对象是左操作数。

全局函数 vs成员函数

大多数运算符都可以重载成成员函数或全局函数。
赋值=、下标[]、函数调用()和成员访问->必须重载成成员函数。
具有赋值意义的运算符,如复合的赋值运算符以及++和--,不一定非要定义为成员函数,但最好定义为成员函数
具有两个运算对象的运算符最好重载为全局函数,这样可以使得应用更加灵活。如果把加运算定义成全局函数,r是有理数类的对象,则2+r是一个合法的表达式。

特殊的运算符的重载

赋值运算符

一般情况下,缺省的赋值运算符重载函数能满足用户的需求。但是,当类含有类型为指针的数据成员时,可能会带来一些麻烦。

赋值运算符只能重载成成员函数,函数原型为:

class  &class::operator=(const class &tight)
{...}

一般来讲,需要拷贝构造函数的类也需要重载赋值运算符。定义对象时给对象赋初值调用的是拷贝构造函数,程序的语句部分中的赋值语句调用的是赋值运算符重载函数。

下标运算符

下标运算符是二元运算符,第一个运算数是数组名,第二个运算数是下标值,下标运算符必须重载成成员函数。
函数原型为:

class & class::operator[](int index)
{...}

函数调用运算符

函数调用运算符()是一个二元运算符。它的第一个运算对象是函数名,第二个参数是形式参数表。运算的结果是函数的返回值。
一个类重载了函数调用运算符,就可以把这个类的对象当做函数来使用

函数调用运算符必须重载成成员函数,函数原型为:

函数的返回值   operator() (形式参数表);

++和—运算符的重载

++--是一元操作符,这两个操作符可以是前缀,也可以是后缀。而且前缀和后缀的含义是有区别的。所以,必须有两个重载函数。
但两个重载函数有相同的原型,区分方法在于:前缀:一元操作符。后缀:二元操作符。

作为成员函数重载:
++ob重载为:class &class::operator++()
ob-- 重载为:class class::operator--(int)
作为友元函数重载:
++ob重载为:operator++(class &ob)
ob--重载为:operator--(class &ob,int)
int没有值的意义,仅仅起到区分作用,调用时,参数int一般传递给值0。

输入输出运算符重载

借助于流插入运算符>>和流提取运算符<<输入和输出用户自定义类的对象。

输入输出运算符必须被重载成全局函数

输入输出运算符是二元运算符,返回的是第一个对象的引用。由于第一个参数是输入输出流对象,只能重载为友元函数。

输出运算符的重载
ostream & operator<<(ostream & os, const class &obj)
{
    os<< ....;
    return os;
}
输入输出运算符重载
istream & operator>>(istream & is, class &obj)
{
    is >> ....;
    return is;
} 

重载函数的原型设计考虑

参数设计

对于任何函数的参数,如果仅需要从参数中读,而不改变它,一般用const引用来传递。
只有会修改左值参数的运算符,如赋值运算符,左值参数不是常量,所以用地址传递。

返回值的类型设计

运算符的结果产生一个新值,就需要产生一个作为返回值的新对象。
对于逻辑运算符,人们希望至少得到一个int或bool的返回值。
所有的赋值运算符(如,=,+=等)均改变左值,应该能够返回一个刚刚改变了的左值的非常量引用。

自定义类型转换运算符

内置类型到类类型的转换

利用构造函数进行转换。例如,对于Rational类的对象r,可以执行r=2。 此时,编译器隐式地调用Rational的构造函数,传给它一个参数2。构造函数将构造出一个num=2,den= 1的Rational类的对象,并将它赋给r。

explicit构造函数

任何单参数的构造函数都可以被编译器用来执行隐式转换,即把内置类型转换成对应的类类型。
在某些情况下,隐式转换是不受欢迎的。
将单参数的构造函数定义为explicit,将告诉编译器不允许执行隐式转换。
如将Ratioanal类的构造函数定义成

 explicit Rational(int n1 = 0, int n2 = 1)

则对于Rational类的对象r1和r2,执行r1 = 2 + r2;编译器就会报错。

类类型到其它类型的转换

可以通过类型转换函数实现,类型转换函数必须重载成成员函数。
类型转换函数的格式:

operator type() const 
{
    return (结果为目标类型的表达式);
}

类型转换函数的特点:无参数,无返回值,是const函数。

有了这个函数,我们可以将一个Rational类的对象r赋给一个type类型的变量x。如r的值为(1,3),经过赋值double x = r后,x的值为0.333333。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,904评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,581评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,527评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,463评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,546评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,572评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,582评论 3 414
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,330评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,776评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,087评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,257评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,923评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,571评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,192评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,436评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,145评论 2 366
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,127评论 2 352

推荐阅读更多精彩内容

  • C++语言的一个很有意思的特性就是除了支持函数重载外还支持运算符重载,原因就是在C++看来运算符也算是一种函数。比...
    欧阳大哥2013阅读 2,702评论 0 8
  • C++运算符重载-上篇 本章内容:1. 运算符重载的概述2. 重载算术运算符3. 重载按位运算符和二元逻辑运算符4...
    Haley_2013阅读 2,293评论 0 51
  • 写在开头:本人打算开始写一个Kotlin系列的教程,一是使自己记忆和理解的更加深刻,二是可以分享给同样想学习Kot...
    胡奚冰阅读 823评论 1 1
  • C++运算符重载-下篇 本章内容:1. 运算符重载的概述2. 重载算术运算符3. 重载按位运算符和二元逻辑运算符4...
    Haley_2013阅读 1,438评论 0 49
  • 注意:本文中代码均使用 Qt 开发编译环境 面向对象的多态性可以分为四类:重载多态、强制多态、包含多态和参数多态,...
    赵者也阅读 1,136评论 0 3