现在的位置: 首页 > 综合 > 正文

关于函数返回值的几种情况

2013年12月03日 ⁄ 综合 ⁄ 共 2124字 ⁄ 字号 评论关闭

关于函数返回值的几种情况 

 

在一个函数的内部,return的时候返回的都是一个拷贝,不管是变量、对象还是指针都是返回拷贝,但是这个拷贝是浅拷贝。

1.     如果返回一个基本类型的变量,比如:

int a;

a = 5;

return a;

那么就会a的一个拷贝,即5返回,然后a就被销毁了。尽管a被销毁了,但它的副本5还是成功地返回了,所以这样做没有问题。

2.     但是对于非动态分配(new/malloc)得到的指针,像1那么做就会有问题,比如在某个函数内部:

int a[] = {1, 2};

return a;

那么也会返回指针a的一个拷贝,我们假定a的地址值为0x002345FC,那么这个0x2345FC是能够成功返回的。当return执行完成后,a就要被销毁,也就是0x002345FC所指向的内存被回收了。如果这时候在函数外面,去地址0x002345FC取值,那得到的结果肯定是不对的。这就是为什么不能返回局部指针的原因。返回局部变量的引用的道理和这个类似。

3.     对于返回(动态分配得到的)指针的另外一种情况,比如在函数内部:

int a = new int(5);

return a;

这样做是可以的。return a执行完后,a并没有被销毁(必须要用delete才能销毁a),所以这里返回的a是有效的。

4.     如果不是基本数据类型,比如:

class A

{

public:

              
OtherClass * ...

};

如果在某个函数内部有一个A类的局部变量,比如:

A a;

return a;

这时候也会返回a的一个拷贝,如果A没有写深拷贝构造函数,就会调用缺省的拷贝构造函数(浅拷贝),这样做就会失败的;

如果A中提供了深拷贝构造函数,则这样做就是可以的。

实验代码如下:

#include<iostream>

usingnamespace std;

int some_fun1()

{

   int a = 5;

   return a;                  
//OK

}

int* some_fun2()

{

   int a = 5;

   int *b = &a;

   return b;                  
// not OK

}

int* some_fun3()

{

   int *c =
newint(5);

   return c;                  
// OK, return c
执行完后并没被销毁必须要用delete才能销毁

}

class CSomething

{

public:

   int a;

   int b;

public:

   CSomething(int a,
int b)

   {

       this->a = a; 

       this->b = b;

   }

};

class CA

{

private:

   CSomething* sth;           
//
以指针形式存在的成员变量

                               

public:

   CA(CSomething* sth)

   {

       this->sth =
new CSomething(sth->a, sth->b);

   }

   //
如果不实现深拷贝,请注释这个拷贝构造函数

   CA(CA& obj)

   {

        sth =
new CSomething((obj.sth)->a, (obj.sth)->b);

   }

   ~CA()

   {

       cout <<
"In the destructor of class CA..." << endl;

       if (NULL != sth)
delete sth;

   }

   void Show()

   {

       cout <<
"(" << sth->a << ", " << sth->b <<
")" << endl;

   }

   void setValue(int a,int b)

   {

       sth->a = a;

       sth->b = b;

   }

   void getSthAddress()

   {

       cout << sth << endl;

   }

};

CA some_fun4()

{

   CSomething c(1, 2);

   CA a(&c);

   return a;                      
//
如果CA没有实现深拷贝not
OK
如果实现深拷贝OK

}

int main(int argc,char*
argv[])

{

   int a = some_fun1();

   cout << a << endl;             
// OK

   int *b = some_fun2();

   cout << *b << endl;            
// not OK
即便返回结果正确也不过是运气好而已

   int *c = some_fun3();          
// OK, return c
执行完后c并没有被销毁必须要用delete才能销毁

   cout << *c << endl;

   delete c;

   CA d = some_fun4();            
//
如果CA没有实现深拷贝not
OK
如果实现深拷贝OK

   d.Show();

   return 0;

}

抱歉!评论已关闭.