More Effective C++ 06:自增、自减操作符前缀形式与后缀形式的区别

重载函数间的区别决定于它们的参数类型上的差异,但是不
论是自增或自减的前缀还是后缀都只有一个参数。为了解决这个语言问题,C++规定后缀形式有一个 int 类型参数,当函数被调用时,编译器传递一个 0 做为 int 参数的值给该函数:

class UPInt 
{ 
public: 
 UPInt& operator++(); // ++ 前缀 
 const UPInt operator++(int); // ++ 后缀 
 UPInt& operator--(); // -- 前缀 
 const UPInt operator--(int); // -- 后缀 
 UPInt& operator+=(int); // += 操作符,UPInts与 ints 相运算  
 ... 
};

要注意的是:这些操作符前缀与后缀形式返回值类型是不同的。前缀形式返回一个引用,后缀形式返回一个const 类型。

UPInt& UPInt::operator++() 
{ 
	*this += 1; // 增加 
	return *this; // 取回值 
} 
// postfix form: fetch and increment 
const UPInt UPInt::operator++(int) 
{ 
	UPInt oldValue = *this; // 取回值 
	++(*this); // 增加 
	return oldValue;

很明显一个后缀自增必须返回一个对象(它返回的是增加前的值),但是为什么 是const对象呢?假设不是const对象,下面的代码就是正确的:

UPInt i; 
i++++; // 两次 increment 后缀 

这组代码与下面的代码相同:

i.operator++(0).operator++(0);

有两个理由导致我们应该厌恶上述这种做法,第一是与内置类型行为不一致。
第二个原因是使用两次后缀自增所产生的结果与调用者期望的不一致。如上所示,第二次调用operator++改变的值是第一次调用返回对象的值,而不是原始对象的值。 因此如果:

i++++;

是合法的,i 将仅仅增加了一次。这与人的直觉相违背,使人迷惑(对于 int 类型和 UPInt 都是一样),所以最好禁止这么做。

如果你很关心效率问题,当你第一次看到后缀自增函数时,你可能觉得有些问题。
这个函数必须建立一个临时对象以做为它的返回值,上述实现代码建立了一个显示的临时对象(oldValue),这个临时对象必须被构造并在最后被析构。前缀自增函数没有这样的临时对象。由此得出一个令人惊讶的结论,如果仅为了提高代码效率,UPInt的调用者应该尽量使用前缀自增,少用后缀 自增,除非确实需要使用后缀自增。让我们明确一下,当处理用户定义的类型时,尽可能地使用前缀自增,因为它的效率较高。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值