2015-05-21 62 views
0

我有一個 std::vector< MyObject* > my_vector; 這不是空的,我想分配並推送一定量的MyObject *。 我知道要推送的對象的數量。有沒有更好的辦法(優化/更快)做比:使用動態對象分配std矢量內容

int object_count = 10000; 
for(int index = 0; index < object_count; index++) 
{ 
    my_vector.push_back(new MyObject()); 
} 

像的malloc一個呼叫分配所有MyObject來,然後memcpy的結果來my_vector。 有什麼想法?

更新 我的問題是調用新的10000次。我希望能夠分配一大塊內存並將內存交換到my_vector的末尾。

+2

你有一個很好的理由使用指針和'new'?使用'vector ',你可以簡單地使用'resize'(或一個合適的構造函數)來添加默認構造的對象。 –

+1

是的,因爲我推送的對象是MyObject的特化。 – Silouane

+0

@Silouane:好,夠公平的。 –

回答

3

您只能在向量中預留足夠的空間,所以它只會分配一次內存。此外,它是使用std ::的unique_ptr一個很好的做法<>:

std::vector<std::unqiue_ptr<MyObject> > my_vector; 
int object_count = 10000; 
my_vector.reserve(object_count); 
for(int index = 0; index < object_count; index++) 
{ 
    my_vector.push_back(std::unique_ptr<MyObject>(new MyObject())); 
} 

更新:如果你不能使用(或不想)使用的unique_ptr,只是增加儲備,以你的代碼預先分配記憶。

更新2:據我瞭解,你想避免內存分配new MyObject()。一個可行的辦法做到這一點是以下(不適合實際應用中使用):

// a very simple example 
class Pool { 
public: 
    Pool() : array(new MySpecObjects[10000]), counter(10000); {} 
    MySpecObject* get() { 
    --counter; 
    return array[counter]; 
    } 
    void reset() { 
    counter = 10000; 
    } 
    MySpecObject* array; 
    size_t counter; 
}; 

static Pool* getPool() { 
    static Pool pool; 
    return pool; 
} 

std::vector<MyObject* > my_vector; 
int object_count = 10000; 
my_vector.reserve(object_count); 
for(int index = 0; index < object_count; index++) { 
    my_vector.push_back(getPool().get())); 
} 

這是一個簡單的例子,它不是線程安全和池,會清除它在程序關機記憶。它背後的想法是類似flyweight gof patternsee boost for example

更新3:也許是更好的解決方案是在這裏使用intrusive lists。然後,您需要做的就是預先分配對象的向量:

class MyObject : public boost::intrusive::list_base_hook<> { 
    ... 
}; 
// MySpecObject1 and MySpecObject2 inherit MyObject 
std::vector<MySpecObject1> objs1(10000); 
std::vector<MySpecObject2> objs2(10000); 
... 

typedef boost::intrusive::list<MyObject> BaseList; 

BaseList list; 
for (MyObject& ref : objs1) { 
    list.push_back(ref); 
} 
for (MyObject& ref : objs2) { 
    list.push_back(ref); 
} 

請注意,BaseList不擁有其節點。當您執行push_back時,列表只是將對象鏈接到現有列表,不執行分配。

+0

'unique_ptr'違反OP的要求。 –

+0

@buttifulbuttefly更新了我的答案,OP可以忽略unique_ptr。 –

+0

但我主要關心的是對新的每個循環增量的調用。 這在我的程序中花費了很多,我想知道是否可以只調用一個新的MyObject [10000]並將結果複製到my_vector? – Silouane

1

有一個標準功能std::generate_n,似乎滿足您的需求:

// Reserve space in vector to prevent unneeded reallocations 
my_vector.reserve(my_vector.capacity() + 10000); 
// Use back inserter to automatically call push_back each time 
// generate_n assigns value. Lambda will be called at each iteration 
// constructing new object. 
std::generate_n(std::back_inserter(my_vector), 10000, 
      []() { return new MyObject; });