如果定义一个类,有其默认的构造函数,则使用new动态实例化一个对象数组,不是件难事,如下代码:
1 #include <memory> 2 #include <iostream> 3 4 using namespace std; 5 6 class Animal 7 { 8 public: 9 #if 1 //用于后面演示,无默认构造函数10 Animal() : num(0)11 {12 cout << "Animal constructor default" << endl;13 }14 #endif15 Animal(int _num) : num(_num)16 {17 cout << "Animal constructor param" << endl;18 }19 20 ~Animal()21 {22 cout << "Animal destructor" << endl;23 }24 25 void show()26 {27 cout << this->num << endl;28 }29 30 private:31 int num;32 };33 34 int main()35 {36 Animal *ani = new Animal[5];37 38 delete[]ani;39 40 system("pause");41 return 0;42 }
运行结果:
但是,如果没有默认构造函数,会出现怎么样呢?
看下图报错提示:
那要如何实例化一个没有默认构造函数的对象数组呢?
下面我将介绍两种方法:
1. 使用C++11新特性allocator类
2. 使用placement new 即operator new(第三个重载版本)void* operator new(size_t size, void *p)函数
对于allocator类,请看 我的另一篇blog http://www.cnblogs.com/SimonKly/p/7819122.html
请看一下代码关于使用如何实现无默认构造函数,动态实例化对象数组的allocator方法
运行结果
通过运行结果可以看出,无论是否有默认构造,allocator会选择出最匹配的构造函数(重载)
函数原型:
void* operator new(size_t size, void* p) throw();
函数执行忽略size,只返回p指针,不分配内存。
placement new具体的用法和相关技术点,请参看我的另一篇博文的第三节
http://www.cnblogs.com/SimonKly/p/7826651.html
具体实现:C++中若类中没有默认构造函数,如何使用对象数组??
请看下面的代码:
1 #include <iostream> 2 3 using namespace std; 4 5 class animal 6 { 7 public: 8 #if 1 //用于后面演示,无默认构造函数 9 animal() : num(0)10 {11 cout << "animal constructor default" << endl;12 }13 #endif14 animal(int _num) : num(_num)15 {16 cout << "animal constructor param" << endl;17 }18 19 ~animal()20 {21 cout << "animal destructor" << endl;22 }23 24 void show()25 {26 cout << this->num << endl;27 }28 29 void * operator new(size_t size, void *p)30 {31 return p;32 }33 34 private:35 int num;36 };37 38 39 int main(int args, char ** argv)40 {41 // 一个动态animal数组42 void *p = operator new(5 * sizeof(animal)); // 申请缓冲器43 animal *a = static_cast<animal *>(p); // 转换类型44 45 // 2.对象构建46 for (int i = 0; i < 4; i++)47 {48 new(a + i) animal(i);// 调用重载构造49 }50 new(a + 4) animal; // 也可以调用默认构造51 52 // 3.使用53 for (int i = 0; i < 5; i++)54 {55 (a + i)->show();56 }57 58 // 4.销毁对象59 for (int i = 0; i < 5; i++)60 {61 (a + i)->~animal();62 }63 64 // 5.回收空间65 delete[]p;66 67 cin.get();68 return 0;69 }
运行结果:
通过运行结果可以看出,无论是否有默认构造,placement new会向已经申请的空间重新构建对象。
联系客服