从函数返回数组

 

摘要: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++标准里没有一个高效的直观的方案来解决数组返回问题,人们往往采用其中比较折中的方案。

相关文章
相关标签/搜索