在CPP中,类是最关键的语法,而类中,初始化又是关键的地方,它决定了类的内存如何分布,编译器如何new出这个类,最常见的两种初始化方法,分别是
- 值初始化形如
OBJ obj1(1,2,3);
的初始化方式 - 列表初始化:形如
OBJ obj2={1,2,3}
也有OBJ obj3{1,2,3};
这种写法
这两种初始化方式有何异同?下面跟随笔者来一起看看函数的调用关系吧吧
struct OBlock {}oblock;
std::ostream& operator<<(std::ostream& os, OBlock ob){os << "\t";return os;}
struct test
{
int a;
int b;
int c;
};
int main()
{
//test t1(1, 2, 3);警告,没有匹配的类型
test t1 = { 1,2,3 };
cout << t1.a << oblock << t1.b << oblock << t1.c;
return 0;
}
结论:在没有构造函数的类中,列表初始化比值初始化更泛用,它从上到下的赋值 结论:在没有构造函数的类中,列表初始化比值初始化更泛用,它从上到下的赋值 结论:在没有构造函数的类中,列表初始化比值初始化更泛用,它从上到下的赋值
struct test
{
int a;
int b;
int c;
test(int i1, int i2, int i3)
{
c = i1; b = i2; a = i3;
cout << "build fun is called" << endl;
}
};
std::ostream& operator<<(std::ostream& os, test t1) { os << t1.a << oblock << t1.b << oblock << t1.c<<endl;; return os; }
int main()
{
test t1(1, 2, 3);
test t2 = { 1,2,3 };
cout << t1;
cout << t2;
return 0;
}
运行结果
build fun is called
build fun is called
3 2 1
3 2 1
结论:在显式的具有构造函数而没有列表化初始器的类中,值初始化和列表初始化都调用构造函数 结论:在显式的具有构造函数而没有列表化初始器的类中,值初始化和列表初始化都调用构造函数 结论:在显式的具有构造函数而没有列表化初始器的类中,值初始化和列表初始化都调用构造函数
struct test
{
int a;
int b;
int c;
test(int i1, int i2, int i3)
{
c = i1; b = i2; a = i3;
cout << "build fun is called" << endl;
}
test(std::initializer_list<int> initl)
{
a = b = c = 0;
cout << "build fun 2is called" << endl;
}
};
std::ostream& operator<<(std::ostream& os, test t1)
{ os << t1.a << oblock << t1.b << oblock << t1.c<<endl;; return os; }
int main()
{
test t1(1, 2, 3);
test t2 = { 1,2,3 };
cout << t1;
cout << t2;
return 0;
}
结果
build fun is called
build fun 2is called
3 2 1
0 0 0
结论:在具有构造函数和列表初始化器的类中,值初始化偏向调用构造函数, 而列表初始化偏向调用列表初始化器函数 结论:在具有构造函数和列表初始化器的类中,值初始化偏向调用构造函数,\\而列表初始化偏向调用列表初始化器函数 结论:在具有构造函数和列表初始化器的类中,值初始化偏向调用构造函数,而列表初始化偏向调用列表初始化器函数