用户名: 密码: 免费注册 忘记密码? 网站地图 | 加入收藏 | 设为首页
首页 | 新闻 | 工具 | 系统 | 办公 | 聊天 | 多媒体 | 网页 | 运营 | 平面 | 欣赏 | 数据库 | 程序 | 服务器 | 组网
网页 | 3dmax | Ghost | Windows Xp| Dreamweaver | photoshop | Flash | office | Alexa | Css | QQ | Asp | PHP | Jsp | Access
Flash MX 2004入门 | 网站推广策略 | CorelDRAW入门 | ASP学习 | 网站建设大师功 | Word入门
  iTbulo.com > 学院 > 正文
C++中的运算符重载函数基础及其值返回状态
iTbulo.COM 2006-4-5 管宁()

  下面我们讨论一下作为类成员函数的运算符重载函数的使用,及其函数的值返回与引用返回的差别。

  下面我们先看实例,而后逐步分析。

代码如下(重要部分做了详细的注解):

 C++ 代码 
 
//程序作者:管宁     
//站点: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指针。

  接下来我们具体分析一下运算符重载函数的值返回与引用返回的差别

  当我们把代码中的加运算重载函数修改成返回引用的时候:

 C++ 代码 
        Test& operator +(Test& temp2)//+运算符重载函数   
        { 
            Test result(this->a+temp2.a);   
            return result;   
        }


  执行运算符重载函数返回引用将不产生临时变量,外部的Test c=a+a; 将获得一个局部的,栈空间内存地址位置上的值,而栈空间的特性告诉我们,当函数退出的时候函数体中局部对象的生命周期随之结束,所以保存在该地址中的数据也将消失,当c对象去获取存储在这个地址中的值的时候,里面的数据已经不存在,导致c获得的是一个随机值,所以作为双目运算的加运算符重载函数是不益采用返回引用方式编写的,当然如果一定要返回引用,我们可以在堆内存中动态开辟空间存储数据,但是这么做会导致额外的系统开销,同时也会让程序更难读懂。


  对于递增运算符来说,它的意义在于能够改变自身,返回引用的函数是可以作为左值参与运算的,所以作为单目运算符,重载它的函数采用返回引用的方式编写是最合适的。

  如果我们修改递增运算符重载函数为值返回状态的时候,又会出现什么奇怪的现象呢?

代码如下:

 C++ 代码 
        Test operator ++() 
        { 
            return this->a++; 
        }


  表面上是发现不出什么特别明显的问题的,但是在main()函数中++(++c);的执行结果却出乎意料,理论上应该是204的值,却只是203,这是为什么呢?
  因为当函数是值返回状态的时候括号内的++c返回的不是c本身而是临时变量,用临时变量参与括号外的++运算,当然c的值也就只改变了一次。结果为203而不是204。


  对于运算符重载函数来说,最后我们还要注意一个问题,当运算符重载函数的形式参数类型全部为内部类型的时候,将不能重载

上一页  [1] [2] 

文章搜索
相关资讯
相关文章 相关下载
C与C++中标准输入实现方式上的一点区别
将成员函数指针强制转换成void*指针
C与C++中标准输入实现方式上的一点区别
为C++标准库容器写自己的内存分配程序
缓冲区溢出还是问题吗?C++/CLI安全编码
焦点信息