最近学习C和C++时遇到了一个问题,那就是C++如何兼容C风格struct的初始化,因此查阅资料并总结一下。
根据查阅cppreference的结果,总结如下
C++的初始化可分为
-
默认初始化
int i; ClassType a; new int;
-
值初始化
ClassType(); ClassType{}; ClassType a{};
-
直接初始化
ClassType a(args);
-
复制初始化
ClassType a=ClassType(args); ClassType a=b;
-
列表初始化
ClassType a={val1, val2}; ClassType a{val1, val2}; ClassType{val1, val2};
-
聚合初始化
int a[5]={0}; StructType a={.data=val1, .next=nullptr}; StructType a={val1, nullptr}; StructType a{val1, nullptr};
-
引用初始化
int& b=a;
注意:ClassType a();
是新手容易犯的初始化错误,这实际上并不是初始化,而是声明函数。
默认初始化与值初始化对比
默认初始化创建的是具名对象,值初始化创建匿名对象。
值初始化会进行内置类型的初始化,例如int初始化为0。
doSomething(int()); //此时int()的值为0
而默认初始化往往不会对内置类型进行初始化
int array[5]; //array中的值是不确定的
对于类来说都是调用默认构造函数
列表初始化与聚合初始化对比
由于C++中的struct与class实际的实现是一样的,为了兼容C语言中struct的初始化(聚合初始化),使用聚合初始化的类型有以下规定
-
数组类型
int array[]{1,2,3,4};
-
所有非静态变量都为public,无用户编写的构造函数,无虚成员函数的类
class TreeNode { public: int data; TreeNode* left; TreeNode* right; }; TreeNode node{1, nullptr, nullptr}; //聚合初始化 TreeNode node{ .data={1}, .left{nullptr}, .right=nullptr}; //聚合初始化
列表初始化要求类具有相应构造函数
- 若类具有std::initializer_list作为唯一参数,或者第一个参数为std::initializer_list,其他参数有默认值的构造函数,则试图匹配参数
- 如果前一个步骤无法完成,则试图与构造函数的参数进行匹配
std::vector<int> a{1,2}; /*列表初始化,调用
std::vector<T,Allocator>::vector(
std::initializer_list<T> init,
const Allocator& alloc = Allocator());*/
std::vector<int> b{a}; /*列表初始化,调用
std::vector<T,Allocator>::vector(
const vector& other);*/
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。