类
类的构造函数/析构函数可不可以私有?
是的,当你定义一个类数组,例如:
| 1 | class_A m[5]; | 
✅ 会调用 class_A 的构造函数,并且会为每个元素调用一次!
当数组 m[5] 的作用域结束或被销毁,也会自动调用析构函数!
🧠 分析细节
假设你的类如下:
| 1 | 
 | 
当你写:
| 1 | class_A m[2]; | 
输出为:
| 1 | Default constructor called | 
🟢 默认构造函数 class_A() 被调用 2次**,每个数组元素都进行一次构造。
❗注意情况 1:构造函数被删除(未定义)、带参数数组 或私有,不能默认构造
| 1 | class class_B { | 
编译器会报错:
| 1 | error: no matching constructor for initialization of 'class_B' | 
📌 原因:数组默认需要无参构造器来初始化每一个元素。
❗构造带参数数组
不能这样写:
| 1 | class_A m[5](1); // ❌ 错误语法 | 
✅ 正确方式:
使用列表初始化或直接初始化各元素:
| 1 | class class_A { | 
✅ 补充:析构函数也会被自动调用
当数组 m[5] 的作用域结束或被销毁:
- 会对每一个元素自动调用析构函数
- 调用顺序是 构造正序;析构反序
| 1 | class_A m[5]; // 构造顺序:m[0] 到 m[4] | 
✅ 结论总结
| 语句 | 是否调用构造函数 | 调用次数 | 
|---|---|---|
| class_A m[5]; | ✅ 是 | 调用默认构造函数5次 | 
| class_A m[5] = {...}; | ✅ 是 | 调用对应构造函数 | 
| 类没有默认构造函数 | ❌ 编译失败 | |
| 构造构造失败 | ❌ 编译失败 | |
| 好的,我们来详细讲解 如何使用列表初始化来初始化一个类数组(也叫统一初始化,在 C++11 引入)。 | 
✅ 假设你有如下类:
| 1 | 
 | 
✅ 初始化类数组的方法:列表初始化(C++11及以上)
你可以用花括号 统一初始化整个数组中的每个对象:
| 1 | MyClass arr[3] = { {1}, {2}, {3} }; | 
🔍 实际做了什么?
这会调用带参数的构造函数:
- MyClass(1)
- MyClass(2)
- MyClass(3)
✅ 相当于如下初始化方式:
| 1 | MyClass arr[3] = { MyClass(1), MyClass(2), MyClass(3) }; | 
🔎 如果构造函数还有多个参数:
| 1 | class MyClass { | 
你可以这样初始化数组:
| 1 | MyClass arr[2] = { {1, 2}, {3, 4} }; | 
✅ 动态数组初始化(vector + 列表初始化)
更现代和灵活的方式是使用 std::vector替代数组:
| 1 | 
 | 
这种方式可以动态扩展,不必提前指定大小,而且初始化语法更直观。
✅ 总结:类数组的列表初始化要点:
- 你可以使用 { {arg1}, {arg2}, ... }块初始化数组中的每个对象
- 必须调用匹配的构造函数
- 如果数量不足,剩余元素必须能调用默认构造函数,否则会编译错误
- 推荐使用 std::vector<T>动态管理对象列表,更安全灵活
动态分配方法(new[])
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Min的博客!
 评论
