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操作符来分配的内存指针,其结果没有被定义的。