2011-06-09 19 views
2

C++ STL向量具有許多不錯的屬性,但只適用於在運行時已知每個項目的大小。具有動態項目大小的C++向量

我想有一個向量類,它在運行時具有動態項目大小。

背景:我的項目由一系列整數和雙打組成;一個只在運行時才知道的序列。只需在運行時爲每個項目指定大小就足夠了。

我知道可能的解決方法,但這些往往不反映算法的基本思想,這對於維護來說始終是件壞事。是否有類提供如人們所期望的那樣高效和方便的工作?

編輯:

這不是關於項的尺寸在整個陣列變化。它有什麼都沒有這樣做。它在運行時決定數組中的項目有多大;即動態類型的(非常)弱形式,與用於模板的靜態類型相反。

因此,對象的初始化應該看起來像:

DynamicVector V(lengthofvector, sizeofelement); 

的應用程序是單純的網格。對象$ V $包含固定大小或「類型」的項目,每個項目包含用於拓撲信息的整數和用於某些幾何信息的雙精度。甚至可能會出現布爾運算,但迄今爲止這並不重要。

+1

聽起來像你想要一個向量的載體。 C++沒有辦法擁有不同大小的對象集合。 – 2011-06-09 14:41:21

+1

我認爲指針向量是您不想使用的變通方法之一? – badgerr 2011-06-09 14:41:53

+0

@尼爾看起來像是對我的回答。 – andrewdski 2011-06-09 14:43:43

回答

1

您可以使用指向您的序列對象的指針vector(最好是智能指針)來簡化向量中的內存管理。

4

問題是,如果您沒有辦法將每個項目的大小存儲在向量中,您將永遠無法獲取數據。

只需將所有物品存儲爲double?這大大簡化了事情。您也可以考慮使用boost::variant

編輯:但你真的可以進一步解釋爲什麼你想在同一個序列中存儲兩種不同類型?這有時可能表明底層設計需要進一步思考。

0

向量表示內存中的連續數組。這是有效的,因爲它可以使用指針算術來通過索引直接訪問元素。但這樣做意味着所有元素具有相同的大小,並且在構建矢量之前知道這個大小。

爲了您的需要,請使用雙向鏈表的元素指針向量。指針矢量幾乎和矢量一樣快。它只需要一種模式的尊重。

如果您的整數和雙精度大小相同(例如64位),您可以使用聯合來訪問每個項目,可以是整數也可以是雙精度。但是你需要一種方法來知道每個元素應該是什麼。

0

如果你不想訴諸於解決方法,我認爲你應該考慮抽象這些「動態大小的項目」。應該銘記,它必須在STL向量(然後一些先決條件必須得到保證),內部使用的設計,這樣你終於可以寫類似:

std::vector<DynamicSizedItem> myVector; 
1

如果它只是int序列, double,那麼你可以簡單地使用:

std::vector<double> sequence; 

,然後插入intdouble進去。但是,這種方法不能跟蹤類型的項目。如果是給你的關鍵,則可能是以下可以幫助你:

struct item 
{ 
    union 
    { 
    int i; 
    double d; 
    } data; 
    char type; //store 0 for int, 1 for double; 
}; 

std::vector<item> sequence; 

當然,這種做法的成本你每個項目ATLEAST一個額外字節,用於存儲的類型該項目。您可能想要使用#pragma pack技術來擠壓額外的填充。

甚至更​​好將重新設計你的代碼,你已經兩個序列而不是一個:

std::vector<int>  intSeq; 
std::vector<double> doubleSeq; 
+2

它可能並且幾乎總是會有多於一個額外的字節:忘記填充填充。 – Fanael 2011-06-09 14:55:30

0

創建包含三個矢量類:一爲整數,一個雙打,和一個具有輸入每個項目以告知相應項目的類型及其在相應向量中的索引。

0

使用std :: vector其中item是一個包裝的智能指針。在「項」級使指針看起來像一個普通值:

class item { 
private: 
    boost:unique_ptr<base> p; 
public: 
    // ... 
    public item(item that); 

    public int someFunction() { 
     // Forwarded 
     return p->somefunction(); 
    } 
}; 

class base { 
    virtual ~base(); 
    // This is needed in order to implement copy of the item class 
    virtual base* clone(); 
}; 

public item::item(item that) : p(that.p.clone()) {} 

class some_real_type() : public base { 
    // .... 
} 
0

我認爲最好的方式向前(在性能和maintaiability方面)是一種變通方法,在那裏你包的std :: vector和std ::在兩個類中插入一個通用的基類和一個適當的接口。

如果你希望它在運行時是動態的,那就是如何正確地做到這一點。它還可以幫助您編寫處理每個項目的高效代碼,以及簡單(但緩慢)地訪問每​​個元素。

0

我以前見過這個問題! Is there an STL container that stores an array of elements in contiguous memory where the element size is specified at runtime?

蓋伊想「交織矢量」(他的話),將持有動態調整大小的物體,通過地圖成員類型和偏移量的定義:

typedef Toffset uint; //byte offset; 
typedef Ttype uint; //enum of types 
typedef std::pair<Toffset,Ttype> member; 
typedef std::unordered_map<std::string, member> memberdefs; 

,我想出了一個(未經測試)班來處理。完整的代碼中的鏈接,但原型是:

class interleaved_vector { 
    const char* buffer; 
    size_t count; 
    size_t size; 
    std::shared_ptr<memberdefs> members; 
public: 
    class dynamic_object { 
     const char* buffer; 
     std::shared_ptr<memberdefs> members; 
     friend interleaved_vector; 
     dynamic_object(const char* buffer_, std::shared_ptr<memberdefs> members_); 
     dynamic_object& operator=(const dynamic_object& b) = delete; 
    public: 
     dynamic_object(const dynamic_object& b) ; 
     template <class T> 
     T get(const std::string& member) const; 
     template <> 
     T* get<T*>(const std::string& member) const; 
     void* operator[](const std::string& member) const; 
    }; 
    interleaved_vector(const char* buffer_, size_t count_, size_t size_, const memberdefs& members_); 
    dynamic_object get(size_t index) const; 
    dynamic_object operator[](size_t index) const; 
    size_t size(); 
}; 

一個警告:它不依賴於一些行爲,我認爲是不確定的,而在一般情況下,是一個壞主意。去與指針的向量。

相關問題