从函数返回数组

从函数返回数组

 
 
 

摘要:C++中存在两种参数传递方式,但语言存在上的数组与一般结构不同,它会在参数传递过程转化为指针,这是从C中继承下来。从而使得在函数中返回数组很困难。本文讲述几种可能的方法。

问题

我们在函数里面准备一个数组,或者说一组数据,现在想把这组数据返回到调用环境中去,就好比如下的代码:

something fun()
{
        int array[3]={ 1, 3, 4};

        return something;
}

int main()
{
        something = fun();
        
        return 0;
}

 

可以说上面的代码看上去很优美,可是在C++如何实现那个fun函数呢?那个something具体是什么内容?

解答

非常遗憾,我没有办法在语言内置数组上实现如此优美的代码;如果我们使用用户数组如类似天vetor对象时,我可以写出这么优美的代码,但是在当前的C++标准(C++03)下它效率很低,在下一代标准中这一点可以实现。

让我们分析一下,要实现传递数组需要哪些准备:

  • 首先数据存储的对象不能是自动生命期的,因为这样的话函数结束时,它会被销毁,所以它只能是静态生命期的或自由生命期的。
  • 通过上面的分析我们产生出两种可能的解决方案:一是返回一个静态数组,二是返回一个动态数组,总之不能返回自动数组。

 

返回静态数组的方案大体代码如下:

int * fun()
{
        static int array[3]={ 1, 3, 4};
        
        return array;
}

这个方案有几个缺点:
  • array的所有权是fun函数的,这个函数是全局的,所以array也是全局的,这意味着array是全局共享的,此时在多线程中必然不安全,甚至是灾难。不可行。
  • 调用环境无法确定array的性质,甚至没有可行的办法知道array的大小,所以就算在单线程中也不具有十分安全。
  • 用户无法更改array的性质,使得这样的函数使用的情况非常有限,不可能大面积使用。

 

之前的C中常有这种方案的出现,但C++不赞成这样使用,因为我们在C++似乎有一个比这个强一点的方案。

返回动态数组的方案要比返回静态数组的方案灵活多变,但也不是很完美,等到C++0x或者C++1x的时候可以改变这个情况。我们给出两个可能的示例代码:

int* fun(size_t n)
{
        int* p = new int[n];
        //do something
        
        return p;
        
        //这个方案最大缺点就是用户需要手工释放内存
        //这在C++社区里不被支持,这些内存管理应该更自动化
}
//可能考虑使用智能指针
smart_ptr fun(size_t n)
{
        smart_ptr<int> p(new int[n]);
        
        //do something
        
        return p;
        
        //这个方案似乎是最好的,它是效率与可用性的折中
        //还有一个思路就是把整个数组都复制出去,它是最直观的,但是效率很差
        //效率差在C++下一代标准中可以得到解决,所谓“右值引用”就是用来解决它的
        //C++下一代标准叫做C++0x或C++1x,本站有相关内容
}

 

总之在现在有C++标准里没有一个高效的直观的方案来解决数组返回问题,人们往往采用其中比较折中的方案。

posted @ 2011-11-24 17:58  有一  阅读(337)  评论(0编辑  收藏  举报