对于类对象的初始化,可以使用传统的构造方式(使用圆括号),也可以使用列表初始化(使用花括号)。
假设有如下类的定义(没有接受 initializer_list 类型参数的构造函数):
class Person {
private:
int weight;
int height;
string name;
public:
Person(int w, int h): weight(w), height(h), name("unknown") {
}
Person(int w, int h, string n): weight(w), height(h), name(n) {
}
};
初始化示例:
Person person1(1, 2); //示例1,调用第一个构造函数
Person person2(1, 2, "haha"); //示例2,调用第二个构造函数
Person person3{1, 2}; //示例3,调用第一个构造函数
Person person4{1, 2, "haha"}; //示例4,调用第二个构造函数
Person person5 = {1, 2, "haha"}; //示例5,调用第二个构造函数
Person person6({1, 2, "haha"}); //示例6,调用第二个构造函数
如果为 Person 类添加接受 initializer_list 类型参数的构造函数:
class Person {
private:
int weight;
int height;
string name;
public:
Person(int w, int h): weight(w), height(h), name("unknown") {
}
Person(int w, int h, string n): weight(w), height(h), name(n) {
}
Person(initializer_list<int> il): name("unknown") {
if (il.size() < 2) {
weight = -1;
height = -1;
} else {
auto iter = il.begin();
weight = *iter++;
height = *iter;
}
}
};
初始化示例:
Person person1(1, 2); //示例1,调用第一个构造函数
Person person2(1, 2, "haha"); //示例2,调用第二个构造函数
Person person3{1, 2}; //示例3,调用了第三个构造函数
Person person4{1, 2, "haha"}; //示例4,由于列表类型不是initializer_list<int>,所以不能调用第三个构造函数;列表内参数类型与第二个构造函数匹配,调用第二个构造函数
Person person5 = {1, 2, "haha"}; //示例5,调用第二个构造函数
Person person6({1, 2, "haha"}); //示例6,调用了第二个构造函数
总结:
-
Object obj = {param1, param2, ...};
和Object obj({param1, param2, ...});
可以直接写成Object obj{param1, param2, ...};
-
Object obj{param1, param2, ...};
会先去匹配 Object 的接受 initializer_list 类型参数的构造函数,即尝试调用Object obj({param1, param2, ...})
,如果匹配不到,然后再去匹配Object obj(param1, param2, ...);
。