C++编程思想笔记——运算符重载

警告和确信

运算符重载仅仅是一个语法修饰,是另一种调用函数的方法而已,除非他会使包含我们的类的代码变得易写,尤其是易读。如果不是这种情况,就不必去重载运算符。

所用于仅保安内部数据类型的表达式的运算符是不可能被改变的,永远不能重载下面的运算符使执行的行为不同:

1 << 4;或是重载运算符使得下面的表达式有意义:1.234 << 4

虽然可以重载几乎所有C中可用的运算符,但使用它们是相当受限制的。特别地,不能结合C中当前没有意义的运算符,不能改变运算符的参数个数

参数和返回值

1.对于任何函数参数,如果仅需要从参数中读取而不改变它,缺省地应当按const引用来传递它。

2.应该选择的返回值取决于运算符所期望的类型

3.所有赋值运算符改变左值。为了使得赋值结果用于链式表达式(A=B=C),应该能够返回一个刚刚改变了左值的引用。编译器从右向左分析这个表达式,并非一定要返回一个nonconst值来支持链式赋值。然而人们有时候希望能对刚刚赋值的对象进行运算((A==B).foo())。因此所有赋值运算符的返回值对于左值应该是nonconst引用。

4.对于逻辑运算符,人们希望至少得到一个int返回值,最好是bool返回值

5.因为有前缀和后缀版本,所以自增和自减运算符出现了两难局面。两个版本都改变对象,所以不能把这个对象看做一个const。因此,前缀版本返回这个对象被改变后的值。这样,用前缀版本我们只需返回*this作为一个引用。因为后缀版本返回改变之前的值,所以被迫创建一个代表这个值的单个对象并返回它。因此,如果想保持我们的本意,对于后缀必须通过传值方式返回。(注意,我们经常会发现自增和自荐运算返回一个int或bool值,例如用来指示是否有一个循环子在表的结尾)。现在的问题是应该按const被返回还是按nonconst被返回?如果允许对象被改变,一些人写了表达式(++A).foo(),则foo()作用在A上。但对于表达式(A++).foo(),foo()作用在通过后缀运算符++号返回的临时对象上。临时对象自动定为const,所以被编译器标记。但为了一致性,使两者都是const更有意义。以为想给自增和自减运算符赋予各种意思,所以他们需要就事论事考虑。

按cosnt通过传值方式返回

返回效率

return integer(left.i + right.i);

一开始看起来像是一个“对一个构造函数的调用",但其实并非如此。这是临时对象语法,它是这样陈述的:”创建一个临时对象并返回它“。如果按照下面方式:

integer tmp(left.i + right.i);

return tmp;

将发生三件事情,首先,tmp对象被创建,与此同时它的构造函数被调用。然后,拷贝构造函数把tmp拷贝到返回值外部存储单元里。最后,当tmp在作用域的结尾时调用析构函数。相反,"返回临时对象"的方法是完全不同的。看到这样情况时,编译器明白对创建的对象没有其他需求,只是返回它,所以编译器直接把这个对象创建在返回值外面的内存单元。因为不是真正创建一个局部对象,所以仅需要单个的普通构造函数调用(不需要拷贝构造函数),并且不会调用析构函数。因此不需要什么花费,效率是非常高的。

不能重载的运算符

成员选择运算符.

成员指针逆向引用运算符.*

不存在用户自定义的运算符,不能编写目前运算符集合中没有的运算符

不能改变优先级规则。


非成员运算符

有时左侧运算符是别的类对象。这种情况通常出现在为iostreams重载运算符<<和>>时候

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值