C++重载++和--(自增和自减运算符)
发布时间:2020-12-16 07:41:39 所属栏目:百科 来源:网络整理
导读:自增运算符 ++ 、自减运算符 -- 都可以被重载,但是它们有前置、后置之分。 以 ++ 为例,假设 obj 是一个 CDemo 类的对象, ++obj 和 obj++ 本应该是不一样的,前者的返回值应该是 obj 被修改后的值,而后者的返回值应该是 obj 被修改前的值。如果如下重载 ++
自增运算符++ 、自减运算符-- 都可以被重载,但是它们有前置、后置之分。以 ++ 为例,假设 obj 是一个 CDemo 类的对象,++obj 和obj++ 本应该是不一样的,前者的返回值应该是 obj 被修改后的值,而后者的返回值应该是 obj 被修改前的值。如果如下重载++ 运算符:
CDemo & CDemo::operator ++ () { //... return * this; }那么不论 obj++ 还是++obj ,都等价于obj.operator++() 无法体现出差别。为了解决这个问题,C++ 规定,在重载 ++ 或-- 时,允许写一个增加了无用 int 类型形参的版本,编译器处理++ 或-- 前置的表达式时,调用参数个数正常的重载函数;处理后置表达式时,调用多出一个参数的重载函数。来看下面的例子:
#include <iostream> using namespace std; class CDemo { private: int n; public: CDemo(int i=0):n(i) { } CDemo & operator++(); //用于前置形式 CDemo operator++( int ); //用于后置形式 operator int ( ) { return n; } friend CDemo & operator--(CDemo & ); friend CDemo operator--(CDemo &,int); }; CDemo & CDemo::operator++() {//前置 ++ n ++; return * this; } CDemo CDemo::operator++(int k ) { //后置 ++ CDemo tmp(*this); //记录修改前的对象 n++; return tmp; //返回修改前的对象 } CDemo & operator--(CDemo & d) {//前置-- d.n--; return d; } CDemo operator--(CDemo & d,int) {//后置-- CDemo tmp(d); d.n --; return tmp; } int main() { CDemo d(5); cout << (d++ ) << ","; //等价于 d.operator++(0); cout << d << ","; cout << (++d) << ","; //等价于 d.operator++(); cout << d << endl; cout << (d-- ) << ","; //等价于 operator-(d,0); cout << d << ","; cout << (--d) << ","; //等价于 operator-(d); cout << d << endl; return 0; }程序运行结果: 5,6,7,7 7,5,5 本程序将 ++ 重载为成员函数,将-- 重载为全局函数。其实都重载为成员函数更好,这里将-- 重载为全局函数只是为了说明可以这么做而已。调用后置形式的重载函数时,对于那个没用的 int 类型形参,编译器自动以 0 作为实参。 如第 39 行, d++ 等价于d.operator++(0) 。对比前置 ++ 和后置++ 运算符的重载可以发现,后置++ 运算符的执行效率比前置的低。因为后置方式的重载函数中要多生成一个局部对象 tmp(第21行),而对象的生成会引发构造函数调用,需要耗费时间。同理,后置-- 运算符的执行效率也比前置的低。前置 ++ 运算符的返回值类型是 CDemo &,而后置++ 运算符的返回值类型是 CDemo,这是因为运算符重载最好保持原运算符的用法。C++ 固有的前置++ 运算符的返回值本来就是操作数的引用,而后置++ 运算符的返回值则是操作数值修改前的复制品。例如:
int a = 5; (++a) = 2;上面两条语句执行后,a 的值是 2,因为 ++a 的返回值是 a 的引用。而 (a++) = 2;这条语句是非法的,因为 a++ 的返回值不是引用,不能作为左值。 -- 运算符的返回值类型的设定和++ 运算符一样。在有的编译器(如Visual Studio)中,如果没有后置形式的重载,则后置形式的自增或自减表达式也被当作前置形式处理。而在有的编译器(如Dev C++)中,不进行后置形式的重载,则后置形式的表达式就会编译出错。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |