相信很多人刚开始学习编程的时候,也是为这个问题烦恼过吧,前缀式与后缀式,在很久之前,式没有办法区别++和--操作符的前缀和后缀的调用的。不过在C++已经得到了扩展。
然而无论式前缀或者后缀,都只有一个参数。为了解决这个问题,C++规定后缀形式有一个int类型的参数,当函数被调用的时候,编译器传递一个0作为int参数给该函数:
class UPInt {
public:
UPInt& operator++(); // ++前缀
const UPInt operator++(int); // ++后缀
UPInt& operator--(); // --前缀
const UPInt operator--(int); // --后缀
.......
}
UPInt i;
++i; // 调用 i.operator++();
i++; // 调用 i.operator++(0);
--i; // 调用 i.operator--();
i--; // 调用 i.operator--(0);
需要注意的是,这些操作符前缀与后缀形式的返回值类型是不同的。前缀形式中返回一个引用,后缀形式返回一个const类型。
区分前缀与后缀其实也很简单,只需要记住一句话:increment的前缀形式叫做“增加然后取值”,后缀形式叫做“取回然后增加”。
// 前缀形式
UPInt& UPInt::operator++() {
*this += 1; // 增加
return *this; // 取回值
}
// 后缀形式
const UPInt UPInt::operator++(int) {
UPInt oldValue = *this; // 取回值
++(*this); // 增加
return oldValue; // 返回被取回的值
}
后缀操作符函数没有使用它的函数,它的参数只是用来区分前缀与后缀函数的调用。如果你很关心效率问题,你可能已经发现,后缀操作符函数必须建立一个临时对象做为它的返回值。这个临时对象必须被构造并在结束是析构。而前缀操作符则没有这样的临时对象。则可以得出结论:如果仅为提高效率,则尽可能使用前缀操作符,少用后缀操作符,除非必须使用后缀操作符。
正如你所看到的,掌握前缀和后缀的increment和decrement是容易的。一旦了解了它们的正确返回值类型以及后缀操作符应该以前缀操作符为基础来实现的规则,就足够了。