1. 大括号初始化
int a = {5};
int a{5};
int *q{};
注意点:不能出现精度降级的情况,例如下面的用法是错误的
int a{5.0}
int a = {5.0}
上述的例子中,将浮点类型降级成了整形,会导致编译报错
2. 自定义初始列
class MyTest {
public:
MyTest(initializer_list<int> init) {
std::cout << "MyTest(initializer_list<int> init)" << std::endl;
for (int num : init) {
std::cout << num << std::endl;
}
}
};
void doTest8() {
MyTest p = { 1,2,3,4,5 };
}
这里自定义了int的list
再看下面的例子
class MyTest {
public:
MyTest(initializer_list<int> init) {
std::cout << "MyTest(initializer_list<int> init)" << std::endl;
for (int num : init) {
std::cout << num << std::endl;
}
}
MyTest(int i) {
std::cout << "MyTest(int i)" << std::endl;
}
};
void doTest8() {
MyTest p = { 1,2,3,4,5 };
MyTest q{ 1 };
MyTest r(1, 2); //这行会报错,无重载
MyTest s(1);
}
如果没有定义MyTest(initializer_list<int> init),那么MyTest q{ 1 };将调用MyTest(int i),所以从优先级上来说,带有初值列的版本要优先于普通的带有明确参数的构造函数。
3. explicit 关键字
这个关键字表示不支持隐士的转换,必须要显示的转换。同样以下面的代码为例子,
class P{
public:
P(int a, int b) {
std::cout << "a:" << a << " b:" << b << std::endl;
}
~P() {
std::cout << "~P() called" << std::endl;
}
P(initializer_list<int> a) {
std::cout << "P(initializer_list<int> a) called" << std::endl;
for (int val : a) {
std::cout << "val==>" << val << std::endl;
}
}
explicit P(int a, int b, int c) {
std::cout << "explicit P called" << std::endl;
}
};
void doTest7() {
P x(1, 2);
P y(1.0, 2.0);
P w = { 1, 2 };
P v = { 1, 2, 3 }; //会报错,不支持这种调用
P u{ 1, 2, 3 }; //这个可以通过
P u( 1, 2, 3 ); //这个可以通过
}
上述P v不能通过的原因是我们的代码中阻止了{ 1, 2, 3 }隐式的成为 P 对象。除非我们是显式的方式,例如u变量。