2013-04-15 83 views
0

我想創建一個簡單的模板ArrayList類,但是當我這樣做使用out調用構造函數分配對象數組中的內存?

T* typeArray = new T[10]; 

此創建的對象的10個實例,調用構造函數的10倍。我如何創建一個空數組,我可以在以後放置對象?

+0

你將如何「以後放置物體」?你必須使用新的佈局,而不是簡單的分配... –

+0

typeArray [index] = ...;這不會工作? –

+0

否。調用賦值運算符需要左側有效的對象。 –

回答

3
template<typename T> 
struct RawMem { 
    alignas(T) unsigned char data[sizeof(T)]; 
    T& get_unsafe() { return *reinterpret_cast<T*>(&data[0]); } 
    T const& get_unsafe() const { return *reinterpret_cast<T const*>(&data[0]); } 
    template<typename... Args> 
    void Construct(Args&&... args) { 
    new (&data[0]) T(std::forward<Args>(args)...); 
    } 
    void Destroy() { 
    get_unsafe().~T(); 
    } 
}; 

RawMem<std::string>* buff = new RawMem<std::string>[10]; 
for (int i = 0; i < 10; ++i) { 
    buff[i].Construct("bob is your uncle"); 
} 
for (int i = 0; i < 10; ++i) { 
    std::cout << buff[i].get_unsafe() << "\n"; 
} 
for (int i = 0; i < 10; ++i) { 
    buff[i].Destroy(); 
} 
delete buff; 

請注意,您完全負責處理何時調用析構函數,何時不調用上述模式。

我包括幫手ConstructDestroy的功能,所以你不必自己動手擺放new之類的東西。同樣,get_unsafe()可讓您在需要時查看T&實例。

以上使用C++ 11 alignas,因爲在C++ 03中沒有辦法解決這個問題。

+0

嘎!爲什麼'buff'不在'unique_ptr'或'auto_ptr'中? –

+0

@BillyONeal缺乏'unique_ptr'的恐怖,但不是在手動構建的對象數組中,沒有描述哪些是構造的,哪些不是? – Yakk

+0

是的。至少你的例子'RawMem'可能會在一些有限的情況下完成一些有用的事情。完全沒有理由在新代碼中手動刪除(除非自己寫RAII類)。當然,某種形式的狀態應該放入'RawMem'中以確保包含的'T'被破壞...... –

5

這不是在C++做事的首選方式,但

T* my_array = (T*)malloc(10 * sizeof(T)); 

與標準C++的做法A線的解決方案更是

std::vector<T> my_vector; 
my_vector.reserve(10); 

注意,(如在評論提到)的與reserve解決方案不同之處在於沒有采取進一步行動my_vector[5]無效,而my_array[5]是。隨後你需要像my_vector.resize(10)這樣的東西來索引它,它將構建全部10個項目。您可以通過做push_back(T const&)emplace_back(Args...&& args)從前到後構建它們。這種方式構建後纔是[]索引合法。作爲警告,[]索引可能在非法時也可以工作,但它是未定義的行爲。

+0

'std :: array'將導致構造函數調用。 +1爲'vector'答案。 –

+0

@BillyONeal認識到,刪除。 –

+0

......你究竟推薦OP用那個'vector'做什麼?因爲有一個正確和錯誤的答案只是掛在那裏...... – Yakk

相關問題