重载运算符函数返回类型和形式参数也是根据需要量进行调整的,下面我们来看一下修改后的加运算符重载函数。
代码如下:
//程序作者:管宁 //站点:www.cndev-lab.com //所有稿件均有版权,如要转载,请务必著名出处和作者 #include <iostream> using namespace std; class Test { public: Test(int a = 0) { Test::a = a; } friend Test operator +(Test&,const int&); public: int a; }; Test operator +(Test& temp1,const int& temp2)//+运算符重载函数 { Test result(temp1.a * temp2); return result; } int main() { Test a(100); Test c = a + 10; cout<<c.a<<endl; system("pause"); }
上面修改后的例子中,我们让重载后的加运算符做的事情,事实上并不是同类型对象的加运算,而是自定义类对象与内置int常量对象的乘法运算。
值得注意的是,对于运算符重载来说,我们并不一定要用它一定要做同类型对象的加法或者是其它运算,运算符重载函数本身就是函数,那么在函数体内部我们是可以做任何事情的,但是从不违背常规思维的角度来说,我们没有必要让重载加运算的函数来做与其重载的符号意义上完全不相符的工作,所以在使用重载运算符脱离原意之前,必须保证有足够的理由。
下面我们讨论一下作为类成员函数的运算符重载函数的使用,及其函数的值返回与引用返回的差别。
下面我们先看实例,而后逐步分析。
代码如下(重要部分做了详细的注解):
//程序作者:管宁 //站点:www.cndev-lab.com //所有稿件均有版权,如要转载,请务必著名出处和作者 #include <iostream> using namespace std; class Test { public: Test(int a = 0) { Test::a = a; } Test(Test &temp) //运算符重载函数为值返回的时候会产生临时变量,临时变量与局部变量result的复制会调用拷贝构造函数,临时变量的生命周期是在拷贝构造函数运行完成后才结束,但如果运算符重载函数返回的是引用,那么不会产生临时变量,而局部变量result的生命周期在运算符重载函数退出后立即消失,它的生命周期要比临时变量短,所以当外部对象获取返回值的内存地址所存储的值的时候,获得是一个已经失去效果的内存地址中的值,在这里的值返回与引用返回的对比,证明了临时变量的生命周期比局部变量的生命周期稍长。 { cout<<"载入拷贝构造函数"<<"|"<<temp.a<<endl;//注意这里,如果修改运算符重载函数为返回引用,这里就会出现异常,temp.a将获得一个随机值。 Test::a = temp.a; } ~Test()//在mian()内析构的过程是result局部变量产生的 { cout<<"载入析构函数!"<<endl; cin.get(); } Test operator +(Test& temp2)//+运算符重载函数 { //cout<<this->a<<endl; Test result(this->a+temp2.a); return result; } Test& operator ++()//++运算符重载函数 //递增运算符是单目运算符,使用返回引用的运算符重载函数道理就在于它需要改变自身。 //在前面我们学习引用的单元中我们知道,返回引用的函数是可以作为左值参与运算的,这一点也符合单目运算符的特点。 //如果把该函数改成返回值,而不是返回引用的话就破坏了单目预算改变自身的特点,程序中的++(++c)运算结束后输出c.a,会发现对象c只做了一次递增运算,原因在于,当函数是值返回状态的时候括号内的++c返回的不是c本身而是临时变量,用临时变量参与括号外的++运算,当然c的值也就只改变了一次。 { this->a++; return *this; } public: int a; }; int main() { Test a(100); Test c=a+a; cout<<c.a<<endl; c++; cout<<c.a<<endl; ++c; cout<<c.a<<endl; ++(++c); cout<<c.a<<endl; system("pause"); }
上例中运算符重载函数以类的成员函数方式出现,细心的读者会发现加运算和递增运算重载函数少了一个参数,这是为什么呢? 因为当运算符重载函数以类成员函数身份出现的时候,C++会隐藏第一个参数,转而取代的是一个this指针。
|