typedef EquipmentPiece* PEP; // PEP 指針指向 //一個EquipmentPiece對象 PEP bestPieces[10]; // 正確, 沒有調用構造函數 PEP *bestPieces = new PEP[10]; // 也正確 在指針數組里的每一個指針被重新賦值,以指向一個不同的EquipmentPiece對象:
for (int i = 0; i < 10; ++i) bestPieces[i] = new EquipmentPiece( ID Number ); 不過這中方法有兩個缺點,第一你必須刪除數組里每個指針所指向的對象。假如你忘了,就會發生內存泄漏。第二增加了內存分配量,因為正如你需要空間來容納EquipmentPiece對象一樣,你也需要空間來容納指針。
// 為大小為10的數組 分配足夠的內存 // EquipmentPiece 對象; 具體情況請參見條款8 // Operator new[] 函數 void *rawMemory = operator new[](10*sizeof(EquipmentPiece)); // make bestPieces point to it so it can be treated as an // EquipmentPiece array EquipmentPiece *bestPieces = static_cast(rawMemory); // constrUCt the EquipmentPiece objects in the memory // 使用"placement new" (參見條款8) for (int i = 0; i < 10; ++i) new (&bestPieces[i]) EquipmentPiece( ID Number ); 注重你仍然得為每一個EquipmentPiece對象提供構造函數參數。這個技術(也稱為數組到指針的思想array-of-pointers)答應你在沒有缺省構造函數的情況下建立一個對象數組。它沒有繞過對構造函數參數的需求,實際上也做不到。假如能做到的話,就不能保證對象被正確初始化。
使用placement new的缺點除了是大多數程序員對它不熟悉外(能使用它就更難了),還有就是當你不想讓它繼續存在使用時,必須手動調用數組對象的析構函數,調用操作符delete[]來釋放 raw memory:
// 以與構造bestPieces對象相反的順序 // 解構它。 for (int i = 9; i >= 0; --i) bestPieces[i].~EquipmentPiece(); // deallocate the raw memory operator delete[](rawMemory); 假如你忘記了這個要求或沒有用這個數組刪除方法,那么你程序的運行將是不可猜測的。這是因為直接刪除一個不是用new操作符來分配的內存指針,其結果沒有被定義的。