自定义 类型的操作符重载,应该与内置类型保持行为一致 。 与内置类型保持行为一致 a++的返回类型如果改成非 const 对象,肯定能通过编译,但是我们最好不要这 样做。 ++a 的返回类型为什么是引用呢? 这样做的原因应该就是:与内置类型的行为保持一致。前置++返回的总是被自增 的对象本身。因此,++(++a)的效果就是 a 被自增两次。 形参的区别 前置++没有形参, 而后置++有一个 int 形参, 但是该形参也没有被用到。 很奇怪, 难道有什么特殊的用意? 其实也没有特殊的用意,只是为了绕过语法的限制 。 为了绕过语法的限制 前置++与后置++的操作符重载函数,函数原型必须不同。否则就违反了“重载函 数必须拥有不同的函数原型”的语法规定。 虽然前置++与后置++的返回类型不同,但是返回类型不属于函数原型。为了绕过 语法限制,只好给后置++增加了一个 int 形参。 原因就是这么简单,真的没其他特殊用意。其实,给前置++增加形参也可以;增 加一个 double 形参而不是 int 形参,也可以。只是,当时就这么决定了。 代码实现的区别 前置++的实现比较简单,自增之后,将*this 返回即可。需要注意的是,一定要 返回*this。 后置++的实现稍微麻烦一些。因为要返回自增之前的对象,所以先将对象拷贝一 份,再进行自增,最后返回那个拷贝。 在 Age 的代码中,后置++利用了前置++来实现自增。这样做是为了避免“自增的 代码”重复。 在本例中,自增的代码很简单,就是一行++i,没有必要这样做。但是在其它自 增逻辑复杂的例子中,这么做还是很有必要的。 效率的区别 如果不需要返回自增之前的值,那么前置++和后置++的计算效果都一样。但是, 我们仍然应该优先使用前置++,尤其是对于用户自定义类型的自增操作。 前置++的效率更高,理由是:后置++会生成临时对象。 从 Age 的后置++的代码实现也可以看出这一点。 Cpp 代码 1. const Age operator++(int //后置++ int) int 2. { 3. Age tmp = *this; 4. ++(*this); //利用前置++ 5. return tmp; 6. } 很明显,tmp 是一个临时对象,会造成一次构造函数和一次析构函数的额外开 销。虽然,编译器在某些情况下可以优化掉这些开销。但是,我们最好不要依赖 编译器的行为。 关于前置++和后置++,基本上就是这些内容。如果还有其他需要注意的地方,欢 迎补充。