2017-03-08 50 views
1

性能是在我的應用固定大小的std :: vector在運行時?

關鍵我需要的東西,就像std::experimental::dynarray,所以它的大小是在運行時決定的數組。

所以我想過使用一個包裝類std::vector,給予其所有功能,但沒有可能打電話resizereservepush_back。用幾句話說,所有的方法來改變它的大小(請記住我,如果我錯過了其中的一些)。

於是我開始寫這個類:

CCVector.hpp

template <typename T> 
class CCVector{ 
public: 
    CCVector(size_t size); 
    T &operator[](typename std::vector<T>::size_type idx); 
private: 
    std::vector<T> v; 
}; 

CCVector.cpp

template<typename T> 
CCVector<T>::CCVector(size_t size) : v(size){} 
template<typename T> 
T& CCVector<T>::operator[](typename std::vector<T>::size_type idx){ 
    return v[idx]; 
} 

但我這一點,我想我必須重新實現的std::vectorevery方法我需要!例如begin,end,size等,我不知道如何實現所有這些...此外,這對維護非常不利:只要我需要一個來自std::vector的新方法,我需要重新實現它在CCVector

所有這一切都是因爲我想在運行時固定大小的數組。如何在不使用非標準std::experimental::dynarray的情況下解決此問題?

+2

只需從std :: vector繼承,然後爲您希望在公開部分中公開的每個函數執行using語句。然後在專用部分對所有要禁用的功能執行using語句。 –

+1

你也可以使用[這裏]的代碼(http://stackoverflow.com/a/15832431/4342498) – NathanOliver

+0

@AlexZywicki,不,不要那樣做;看到[你不應該從'std :: vector']繼承](http://stackoverflow.com/questions/4353203/thou-shalt-not-inherit-from-stdvector) –

回答

6

使用私有繼承,然後使用聲明using導入您想要的函數,以將您想要的名稱引入您的類。

template<class T> 
class MyVector : private std::vector<T> 
{ 
public: 
    using std::vector<T>::end; 
    // etc 
}; 

+1

這正是我的意思。 –

+0

這是一個很好的解決方案嗎?正如我在更新後的問題中所寫的,性能在我的應用程序中至關重要 – justHelloWorld

+1

@justHelloWorld這與使用'std :: vector'一樣快。 – Galik

0

你是正確的,std::vector有(有私有繼承你不沒有虛析構函數這是大多數人不喜歡從標準集裝箱繼承的原因矢量得到問題)相當多的成員函數需要暴露給外部,但沒有很多。例如,看到這裏http://www.cplusplus.com/reference/vector/vector/

此外,你不需要(也不應該)自己實現std::vector - 依靠經過測試的快速代碼,像STL幾乎總是更好的選擇。

因此,而不是重新實現,簡單的「前進」的功能外,像這樣:

iterator begin() 
{ 
    return v.begin(); 
} 

這是一個位的樣板代碼,但是如果你不調整大小功能,做一次std::vector,你完成了。

編輯:

另外,不要從 std::vector繼承。這是一個壞主意,原因很多。

好的,我在這裏有點快,對不起。正如評論和this post所暗示的那樣,從STL容器繼承並不是天生就不好。特別是如果您使用私有繼承,它可能只是給定任務的有效解決方案。

+2

從矢量繼承是一個壞主意,原因很多?沒有人願意解釋的理由比「不這樣做」,這很糟糕「 –

+1

@AlexZywicki相當。我見過的主要原因是虛擬破壞,但這是可以避免的。 「用戶不知道如何使用該類」等其他內容並不特定於此。 luc如果您列出了從標準容器繼承的問題,則OP可以自行決定是否適用於他們的情況。 –

+0

@AlexZywicki我不知道*許多原因,但是我知道* public *繼承是危險的,因爲它意味着* std :: unique_ptr > ptr = new derived'是可以的,當它實際上有UB。 – user2079303

0

私自繼承std::vector正如在其他答案中提出的是一種方法。

使用可調整大小的容器時,會存在一些內存開銷,其中不可調整大小就足夠了。 std::vector通常約爲數據指針的約4倍大小。您可以存儲一個數據指針+長度的一半:

template<class T> 
class dynarray 
{ 
    std::unique_ptr<T[]> data; 
    T*     end; // or size_t size 

    //TODO functions 
}; 

的明顯缺點是,你必須重新實現所有的樣板,你可以以其他方式從std::vector繼承。也就是說,所有的樣板都很簡單 - 只有很多。