返回值的理解

返回值的理解

class A

{

……..

};

一直以来搞不清“返回值”这个概念,今天总算搞清楚了。

我们知道返回值有三种方式:

第一种:“普通”方式,例如,

 A fun()

 {

     A a;

     ...

     return a;

 }

第二种:const方式,例如

      const A fun()

   {

          A a;

            ...

           return a;

   }

第三种:const+引用方式,例如

 const A& fun(const A& a)

 {  

        ...        

        return a;

 }

首先我们得弄清楚返回值的机制,我们做一下测试:

#include <iostream.h>

class A

{

public:

       int a;

       int b;

       static int cnt;//调用次数

       A();

       A(const A &rhs);

};

int A::cnt = 1;

A::A()

{

       a = 0;

       b = 0;

       cout<<this<<endl;

       cout<<"Construct be performanced "<<cnt<<" times."<<endl;

       cnt++;

}

A::A(const A &rhs)

{

       cout<<this<<endl;

       cout<<"Copy Construct be performanced"<<endl;

       a = rhs.a;

       b = rhs.b;

}

const A Fun()

{

       A aa;

       return aa;

}

int main()

{

       A bb = Fun();

       return 0;

}

1

程序的运行结果是,构造函树调用了1次、拷贝构造函数被调用了2次,输出了三个不同的this指针的地址,因此我们可以得出结论,整个程序在运行过程钟产生了三个对象。其中的两个对象是显而易见的,一个是Fun()中的aa,一个是main()中的bb,那么还有一个是哪里来的呢。是返回值,以前对我返回值的理解“fun ()的返回值 == aa”,现在看来是错误的。在bbfunc()赋值之前,编译器生成了一个返回值。

为了进一步证明我们把main()函数改为:

int main()

{

       cout<<Fun().a<<endl;

       return 0;

}

运行结果:

第二个地址值就是返回值(对象)所在的地址。

第三中方式因为传回的是引用,“fun ()的返回值 == aa”在这种情况是成立的。我们把fun()改为:

const A& Fun()

{

       A aa;

       return aa;

}

这时的运行结果

不过这样做存在一个巨大的隐患,如果把A bb = Fun();改为

A &bb = Fun();

因为aa是一个局部变量,它的生命周期在A &bb = Fun();语句子后就结束了。这时如果编译程序将报错。

结论:

1.当函数带返回值时,有一个看不见的返回值变量

2,返回值的第一种方式和第二种方式的区别是第二种方式中返回值是const型的,在直接用返回值不可改变其值

3.对于A bb = fun ()这样的语句(fun()的返回值采用的是第一种和第二种方式),是直接调用拷贝构造函数而非赋值运算符。

4.第三种方式可认为“fun ()的返回值 == aa”,但应注意return后的变量不为局部变量,如果是动态变量(在堆上申请内存),应注意delete,建议不要这么用,

因为newdelete不在同一个函数中,很容易被遗忘。

 

 

这里引发我的另一个问题,为什么A bb = fun() 调用的是拷贝构造函数而不是赋值运算符。我猜测是不是赋值函数调用了拷贝函数(其实稍加推敲就知道这个想法是错误的,因为调用一个拷贝构造函数就意味新生成了一个对象,而在调用赋值运算符之前,肯定已经调用了一个构造函数,而一个对象是不可能调用类的两个构造函数的(指同一个类的两个构造函数))。为了弄清这个问题,我为class A 重载了“=”运算符:

const A A::operator=(const A& rhs)

{

       cout<<this<<endl;

       cout<<"Evaluate function be performanced"<<endl;

       a = rhs.a;

       b = rhs.b;

       return *this;

}

但运行的结果依然与(1)一样。但如果把 A bb = fun();改为

A bb;

       bb = Fun();

这时的运行结果

调用了普通构造函数和赋值运算符。因此得出结论:

bb = fun();

A bb;

       bb = Fun();

的运行方式是不一样的。

 

  • 2
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值