從函式返回陣列
阿新 • • 發佈:2019-01-30
摘要: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]
return array;
}
這個方案有幾個缺點:
- array的所有權是fun函式的,這個函式是全域性的,所以array也是全域性的,這意味著array是全域性共享的,此時在多執行緒中必然不安全,甚至是災難。不可行。
- 呼叫環境無法確定array的性質,甚至沒有可行的辦法知道array的大小,所以就算在單執行緒中也不具有十分安全。
- 使用者無法更改array的性質,使得這樣的函式使用的情況非常有限,不可能大面積使用。
之前的C中常有這種方案的出現,但C++不贊成這樣使用,因為我們在C++似乎有一個比這個強一點的方案。
返回動態陣列的方案要比返回靜態陣列的方案靈活多變,但也不是很完美,等到C++0x或者C++1x的時候可以改變這個情況。我們給出兩個可能的示例程式碼:
{
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++標準裡沒有一個高效的直觀的方案來解決陣列返回問題,人們往往採用其中比較折中的方案。