首页 | 编程语言 | 网站建设 | 游戏天堂 | 冲浪宝典 | 网络安全 | 操作系统 | 软件时空 | 硬件指南 | 病毒相关 | IT 认证
软讯网络 > 编程语言 > C/C++ > More Effective C++ 条款6:自增(increment)、自减(decrement)操作符前缀形式与后缀形式的区别
【标  题】:More Effective C++ 条款6:自增(increment)、自减(decrement)操作符前缀形式与后缀形式的区别
【关键字】:More,Effective,C++,increment,decrement
【来  源】:http://blog.csdn.net/wang_junjie/archive/2006/09/06/1185668.aspx

More Effective C++ 条款6:自增(increment)、自减(decrement)操作符前缀形式与后缀形式的区别

很久以前(八十年代),没有办法区分++和--操作符的前缀与后缀调用。这个问题遭到
程序员的报怨,于是C++语言得到了扩展,允许重载increment 和 decrement操作符的两
种形式。
然而有一个句法上的问题,重载函数间的区别决定于它们的参数类型上的差异,但是不
论是increment或decrement的前缀还是后缀都只有一个参数。为了解决这个语言问题,
C++规定后缀形式有一个int类型参数,当函数被调用时,编译器传递一个0做为int参数
的值给该函数:
class UPInt { // "unlimited precision int"
public:
UPInt& operator++(); // ++ 前缀
const UPInt operator++(int); // ++ 后缀
UPInt& operator--(); // -- 前缀
const UPInt operator--(int); // -- 后缀
UPInt& operator+=(int); // += 操作符,UPInts
// 与ints 相运算
...
...
};
UPInt i;
++i; // 调用 i.operator++();
i++; // 调用 i.operator++(0);
--i; // 调用 i.operator--();
i--; // 调用 i.operator--(0);
这个规范有一些古怪,不过你会习惯的。而尤其要注意的是这些操作符前缀与后缀形式
返回值类型是不同的。前缀形式返回一个引用,后缀形式返回一个const类型。下面我们
将讨论++操作符的前缀与后缀形式,这些说明也同样使用与--操作符。
从你开始做C程序员那天开始,你就记住increment的前缀形式有时叫做“增加然后取回
”,后缀形式叫做“取回然后增加”。这两句话非常重要,因为它们是increment前缀与
后缀的形式上的规范。
// 前缀形式:增加然后取回值
UPInt& UPInt::operator++()
{
*this += 1; // 增加
return *this; // 取回值
}
// postfix form: fetch and increment
const UPInt UPInt::operator++(int)
{
UPInt oldValue = *this; // 取回值
++(*this); // 增加
return oldValue; // 返回被取回的值
}
后缀操作符函数没有使用它的参数。它的参数只是用来区分前缀与后缀函数调用。如果
你没有在函数里使用参数,许多编译器会显示警告信息,很令人讨厌。为了避免这些警
告信息,一种经常使用的方法时省略掉你不想使用的参数名称;如上所示。
很明显一个后缀increment必须返回一个对象(它返回的是增加前的值),但是为什么是
const对象呢?假设不是const对象,下面的代码就是正确的:
UPInt i;
i++++; // 两次increment后缀
// 运算
这组代码与下面的代码相同:
i.operator++(0).operator++(0);
很明显,第一个调用的operator++函数返回的对象调用了第二个operator++函数。
有两个理由导致我们应该厌恶上述这种做法,第一是与内置类型行为不一致。当设计一
个类遇到问题时,一个好的准则是使该类的行为与int类型一致。而int类型不允许连续
进行两次后缀increment:
int i;
i++++; // 错误!
第二个原因是使用两次后缀increment所产生的结果与调用者期望的不一致。如上所示,
第二次调用operator++改变的值是第一次调用返回对象的值,而不是原始对象的值。因
此如果:
此如果:
i++++;
是合法的,i将仅仅增加了一次。这与人的直觉相违背,使人迷惑(对于int类型和UPIn
t都是一样),所以最好禁止这么做。
C++禁止int类型这么做,同时你也必须禁止你自己写的类有这样的行为。最容易的方法
是让后缀increment 返回const对象。当编译器遇到这样的代码:
i++++; // same as i.operator++(0).oper
ator++(0);
它发现从第一个operator++函数返回的const对象又调用operator++函数,然而这个函数
是一个non-const成员函数,所以const对象不能调用这个函数。如果你原来想过让一个
函数返回const对象没有任何意义,现在你就知道有时还是有用的,后缀increment和de
crement就是例子。(更多的例子参见Effective C++ 条款21)
如果你很关心效率问题,当你第一次看到后缀increment函数时, 你可能觉得有些问题。
这个函数必须建立一个临时对象以做为它的返回值,(参见条款19),上述实现代码建
立了一个显示的临时对象(oldValue),这个临时对象必须被构造并在最后被结构。前
缀increment函数没有这样的临时对象。由此得出一个令人惊讶的结论,如果仅为了提高
代码效率,UPInt的调用者应该尽量使用前缀increment,少用后缀increment,除非确实
需要使用后缀increment。让我们明确一下,当处理用户定义的类型时,尽可能地使用前
缀increment,因为它的效率较高。
我们再观察一下后缀与前缀increment 操作符。它们除了返回值不同外,所完成的功能
是一样的,即值加一。简而言之,它们被认为功能一样。那么你如何确保后缀incremen
t和前缀increment的行为一致呢?当不同的程序员去维护和升级代码时,有什么能保证
它们不会产生差异?除非你遵守上述代码里的原则,这才能得到确保。这个原则是后缀
increment和decrement应该根据它们的前缀形式来实现。你仅仅需要维护前缀版本,因
为后缀形式自动与前缀形式的行为一致。
正如你所看到的,掌握前缀和后缀increment和decrement是容易的。一旦了解了他们正
确的返回值类型以及后缀操作符应该以前缀操作符为基础来实现的规则,就足够了。
 
More Effective C++ 条款7:不要重载overload &&, ||, or ,.:【上一篇】
More Effective C++ 条款1:指针与引用的区别:【下一篇】
【相关文章】
  • More Effective C++ 条款7:不要重载overload &&, ||, or ,.
  • 第一篇译作:Working With Unicode in C++(在c++中使用Unicode)
  • 使用 Boost.Python 嵌入 Python 模块到 C++
  • 探索C++的秘密之详解extern "C"(zz)
  • C++拷贝构造函数/深拷贝/浅拷贝
  • C/C++中static和extern
  • C/C++内存管理
  • C++静态成员函数
  • C#、Java以及C++的泛型
  • 《Effective C#》Item 13:使用静态构造函数初始化静态成员
  • 【随机文章】
  • 继承
  • C# 编码规则(实例版)
  • 我整理的关于硬件信息查看的命令
  • 设想一种防U盘病毒的方法,不知道是否管用
  • Microsoft Internet Explorer未明CHM文件处理任意代码执行漏洞
  • 联想借网络营销造世界品牌
  • 中国Linux公社校园行动专题区第七次成员会议
  • [原创]NickLee.Framework.2.0.1.2
  • 内存数据库--ALTIBASE
  • Red Hat Linux 的主要系统目录及其简单描述
  • 【相关评论】
    没有相关评论
    【发表评论】
    姓名:
    邮件:
    随机码*
    评论*
          
    |  首 页  |  版权声明  |  联系我们   |  网站地图  |
    CopyRight © 2004-2007 软讯网络 All Rigths Reserved.