函数返回值

在一个函数的内部,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>

using namespace 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 = new int(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;如果实现深拷贝,则O

    d.Show();


    return 0;
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值