2013-02-15 265 views
2

來自Java背景,我想了解C++中的指針/引用。我試圖從函數返回一個向量。寫作:C++ - 函數返回向量

vector<char*> f(){ 
    vector<char*> vec; 
    return vec; 
} 

將返回向量的副本,是否正確?更好的方法是返回像這樣的向量的指針:

vector<char*>* f(){ 
    vector<char*>* vec = new vector<char*>; 
    return vec; 
} 

我是對的嗎,還是完全錯了?

+0

我不是說它是重複的,但是這個問題很好地討論了這個問題的各個方面:http://stackoverflow.com/questions/3350385/how-to-return-an-object-in-c – jogojapan 2013-02-15 01:19:07

回答

0

你錯了,你不想在C++中做到這一點。幾乎每個C++編譯器都有稱爲命名返回值優化的命名返回值優化,這將通過爲堆棧上的返回值分配空間來有效地移動vec,而不是複製它,然後基本上「構建」 。這消除了開銷。

Wikipedia這篇文章給出了一個合理的概要。

0

我是正確的,還是完全錯誤?

這是完全錯誤的,至少在C++ 11中移動語義存在,只要你不需要創建別名返回值(這似乎不被你的情況,即使它是,可能需要使用智能指針而不是原始指針)。

現在按值返回一個向量即可。大多數情況下,即使在C++ 98中,編譯器也會將調用複製到複製構造函數(以及C++ 11中的移動構造函數)。這被稱爲(Named) Return Value Optimization

在C++ 11中,標準庫的所有容器都支持移動構造函數,因此,即使未複製或移動時,通過值返回容器也不昂貴。

+0

我說的是前11 – Bober02 2013-02-15 01:05:27

+0

這仍然不是一個問題,即使使用C++ 03代碼。 – Yuushi 2013-02-15 01:08:35

1

在C++ 03中,按值返回最有可能導致RVO(返回值優化),從而避免不必要的副本。在C++ 11移動語義將照顧副本。

那麼,爲什麼按價值回報呢?因爲它可以防止不必要的對象具有動態生存期您的示例代碼也不尊重您的函數的用戶可能要使用的任何分配策略。

一般來說,在C++ 11中返回一個容器甚至是一個壞主意:它將用戶限制在特定的容器中,因爲它不可能跨容器移動,只能複製。標準庫通過OutputIteratorS解決了這個問題。你的算法很可能寫成:

template<typename OutputIterator> 
OutputIterator f(OutputIterator o); 

這樣你就從容器中抽象出來,同時繞開了原來的問題。