作者cppOrz (cppOrz)
看板C_and_CPP
標題[心得] 建立帶有初始化參數的 Array
時間Fri Aug 26 05:45:24 2005
這個問題是有關 Array 的應用。印象中好像在 C++ Primer 中看過,但
手邊沒有書,不是很確定。
問題是這樣的,當 class T 不帶有預設建構式(default ctor)時,或
當我們希望使用 class T 的非 default ctor 建立 Array 時,會遭到
一定的麻煩:
class T
{
public :
T(int); // T 沒有 default ctor
};
int arg = ...; // 假設 arg 是欲建立 T 物件時所帶的引數
T array[N](arg); // 當 N 是編譯期常量時
T *p = new T[N](arg); // 當 N 不是編譯期常量時,使用 new
不幸的是,以上兩種方式都是錯誤的,C++ 不支援這種語法。
解決的辦法是先配置一塊足夠的空間,再使用 placement new 的技術:
T *p= reinterpret_cast<T*>(operator new(N*sizeof(T)));
for (int i=0; i<N; ++i)
{
new (p+i) T(arg); // placement new
}
當然,物有其生必有其滅,使用 placement new 建立的物件,別忘了要
透過顯示呼叫 dtor 來解構。
for (int i=0; i<N; ++i)
{
(p+i)->~T(); // class T 內部若有動態配置,這一步驟就是必須的
}
operator delete(p); // 另外,p 是 operator new 來的,要這樣釋放。
當 N 是編譯期的常量時,空間也可以是局部變量:
char data[N*sizoef(T)];
如此建立的動作就改成:
for (int i=0; i<N; ++i)
{
new (&data[i*sizeof(T)]) T(arg); // placement new
}
而在此情況下就不需要 operator delete 了,但是一個個解構還是必須的
一定很多人會認為,這實在是太麻煩了!沒錯,會這樣想通常是很好的。
像上面的問題,一般是推薦大家使用 vector 來取代 Array:
std::vector v(N, T(arg));
一行就搞定了,不用管什麼複雜頭痛的語法規則,也不用操心資源管理的
問題。而且 vector 還有許多其他的好處,例如帶有 value 語義,邊界
檢查、延伸性、與標準程式庫合作較自然……等等,不但方便,而且安全
得多。
既然如此,為何還要介紹 placement new 的辦法呢?原因是某些情況下,
當有極端的性能需求時,vector 就顯得不夠輕便伶俐,手動管理的技術還
是必須的。
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 59.120.214.120
推 khoguan:早安。大大還沒睡嗎,還是都這麼早起呢?220.130.208.168 08/26
推 khoguan:推 鞭辟入裡的講解220.130.208.168 08/26
※ 編輯: cppOrz 來自: 59.120.214.120 (08/26 11:29)
→ cppOrz:是剛起來後寫的,但睡很久了,不能算早起 59.120.214.120 08/26
※ 編輯: cppOrz 來自: 59.120.214.120 (08/26 12:07)