分享

C++中若类中没有默认构造函数,如何使用对象数组

 牛人的尾巴 2018-10-12

前言:

如果定义一个类,有其默认的构造函数,则使用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 #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 }
复制代码

运行结果:

 

 

但是如果没有默认构造函数,会出现怎么样呢?

看下图报错提示:

 

那要如何实例化一个没有默认构造函数的对象数组呢?

下面我将介绍两种方法:

    1. 使用C++11新特性allocator类 

    2. 使用placement new 即operator new(第三个重载版本)void* operator new(size_t  size, void *p)函数 

 

一、allocator类

对于allocator类,请看 我的另一篇blog   http://www.cnblogs.com/SimonKly/p/7819122.html

请看一下代码关于使用如何实现无默认构造函数,动态实例化对象数组的allocator方法 

View Code

 

运行结果

通过运行结果可以看出,无论是否有默认构造,allocator会选择出最匹配的构造函数(重载) 

 

二、placement new

函数原型:

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 #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     // 一个动态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会向已经申请的空间重新构建对象。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多