前言:如果定義一個(gè)類,有其默認(rèn)的構(gòu)造函數(shù),則使用new動(dòng)態(tài)實(shí)例化一個(gè)對(duì)象數(shù)組,不是件難事,如下代碼: 1 #include <memory>
2 #include <iostream>
3
4 using namespace std;
5
6 class Animal
7 {
8 public:
9 #if 1 //用于后面演示,無默認(rèn)構(gòu)造函數(shù)
10 Animal() : num(0)
11 {
12 cout << "Animal constructor default" << endl;
13 }
14 #endif
15 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 }
運(yùn)行結(jié)果:
但是,如果沒有默認(rèn)構(gòu)造函數(shù),會(huì)出現(xiàn)怎么樣呢? 看下圖報(bào)錯(cuò)提示:
那要如何實(shí)例化一個(gè)沒有默認(rèn)構(gòu)造函數(shù)的對(duì)象數(shù)組呢? 下面我將介紹兩種方法: 1. 使用C++11新特性allocator類 2. 使用placement new 即operator new(第三個(gè)重載版本)void* operator new(size_t size, void *p)函數(shù)
一、allocator類對(duì)于allocator類,請(qǐng)看 我的另一篇blog http://www.cnblogs.com/SimonKly/p/7819122.html 請(qǐng)看一下代碼關(guān)于使用如何實(shí)現(xiàn)無默認(rèn)構(gòu)造函數(shù),動(dòng)態(tài)實(shí)例化對(duì)象數(shù)組的allocator方法
View Code
運(yùn)行結(jié)果
通過運(yùn)行結(jié)果可以看出,無論是否有默認(rèn)構(gòu)造,allocator會(huì)選擇出最匹配的構(gòu)造函數(shù)(重載)
二、placement new函數(shù)原型: void* operator new(size_t size, void* p) throw(); 函數(shù)執(zhí)行忽略size,只返回p指針,不分配內(nèi)存。
placement new具體的用法和相關(guān)技術(shù)點(diǎn),請(qǐng)參看我的另一篇博文的第三節(jié) http://www.cnblogs.com/SimonKly/p/7826651.html
具體實(shí)現(xiàn):C++中若類中沒有默認(rèn)構(gòu)造函數(shù),如何使用對(duì)象數(shù)組??
請(qǐng)看下面的代碼: 1 #include <iostream> 2 3 using namespace std; 4 5 class animal 6 { 7 public: 8 #if 1 //用于后面演示,無默認(rèn)構(gòu)造函數(shù) 9 animal() : num(0) 10 { 11 cout << "animal constructor default" << endl; 12 } 13 #endif 14 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 // 一個(gè)動(dòng)態(tài)animal數(shù)組 42 void *p = operator new(5 * sizeof(animal)); // 申請(qǐng)緩沖器 43 animal *a = static_cast<animal *>(p); // 轉(zhuǎn)換類型 44 45 // 2.對(duì)象構(gòu)建 46 for (int i = 0; i < 4; i++) 47 { 48 new(a + i) animal(i);// 調(diào)用重載構(gòu)造 49 } 50 new(a + 4) animal; // 也可以調(diào)用默認(rèn)構(gòu)造 51 52 // 3.使用 53 for (int i = 0; i < 5; i++) 54 { 55 (a + i)->show(); 56 } 57 58 // 4.銷毀對(duì)象 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 }
運(yùn)行結(jié)果:
通過運(yùn)行結(jié)果可以看出,無論是否有默認(rèn)構(gòu)造,placement new會(huì)向已經(jīng)申請(qǐng)的空間重新構(gòu)建對(duì)象。 |
|
|