返回值的理解

原创 2006年05月29日 16:44:00

返回值的理解

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();

的运行方式是不一样的。

 

从springmvc源码看方法参数绑定的注解和返回值处理

从springmvc源码看参数绑定注解和返回值注解
  • gufachongyang02
  • gufachongyang02
  • 2015年04月15日 12:57
  • 2234

Python学习笔记之函数作为返回值、闭包的解释

函数作为返回值高阶函数除了可以接受函数作为参数外,还可以把函数作为结果值返回。我们来实现一个可变参数的求和。通常情况下,求和的函数是这样定义的:def calc_sum(*args): ax ...
  • u010870518
  • u010870518
  • 2015年04月18日 18:52
  • 2243

python-返回函数的理解

最近接触python,看到了python中返回函数的概念,以前只接触过函数返回值,比如python就可以返回int,str,list,dict等等类型数据,这里要说的是python还支持返回函数。首先...
  • CV_YOU
  • CV_YOU
  • 2017年04月27日 22:25
  • 1641

关于对于C语言中主函数参数接返回值的理解

main函数的返回值 main函数的返回值用于说明程序的退出状态。如果返回0,则代表程序正常退出;返回其它数字的含义则由系统决定。通常,返回非零代表程序异常退出。 很多人甚至市面上的一些书籍,都使...
  • YinJianxiang
  • YinJianxiang
  • 2017年06月02日 00:06
  • 384

关于asp.net mvc中Controller中的方法返回值类型ActionResult及其子类的理解

理解ASP.NET MVC中的ActionResult 通常我们在一个ASP.NET MVC项目中创建一个Controller的时候,Index()方法默认的返回类型都是ActionResult,通...
  • weixin_37848710
  • weixin_37848710
  • 2017年12月14日 13:23
  • 144

探讨c++函数中的参数传递与返回值(一) 概念介绍与理解

本文从编译器角度,通过反汇编手段,深入的理解了1.引用的理解与使用2.结构体和类做参数时的底层实现,并对函数参数和返回值的各种情况做了归纳。希望能对大家有用,也希望大家能针对本文中的一些不足和缪误给予...
  • cooljuly
  • cooljuly
  • 2013年01月05日 09:45
  • 774

C++函数参数和返回值三种传递方式:值传递、指针传递和引用传递(着重理解)

C++函数参数和返回值三种传递方式:值传递、指针传递和引用传递(着重理解) 引用与指针的比较 引用是 C++中的概念,初学者容易把引用和指针混淆一起。一下程序中,n 是m 的 一个引用(refe...
  • THISISPAN
  • THISISPAN
  • 2012年04月13日 01:10
  • 2477

CMystring类实现以及返回值的理解

///////////////////////////////////////////////////////////////////// // Filename: mystring.h //////...
  • damotiansheng
  • damotiansheng
  • 2014年02月18日 15:03
  • 604

深入理解主函数main()的输入参数及返回值问题

C语言之Main函数返回值问题分析: 很多人甚至市面上的一些书籍,都使用了void main( ) ,其实这是错误的。C/C++ 中从来没有定义过void main( ) 。C++ 之父 Bjarne...
  • zyazky
  • zyazky
  • 2016年09月22日 11:37
  • 329

帮助大家理解一下递归函数的返回值...

如题: 递归函数往往可以简化我们的代码,尤其是对树的遍历和利用回溯算法写代码的时候,但是递归函数的返回值往往是困扰我们的。 总体来说,我们先要理解函数的调用过程,函数调用过程会用栈来保存函数的返回...
  • code_mover
  • code_mover
  • 2016年07月08日 20:00
  • 1935
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:返回值的理解
举报原因:
原因补充:

(最多只允许输入30个字)