[C++11]统一的数据初始化方式 - 初始化列表
Posted Wecccccccc
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[C++11]统一的数据初始化方式 - 初始化列表相关的知识,希望对你有一定的参考价值。
关于C++中的变量,数组,对象等都有不同的初始化方法,在这些繁琐的初始化方法中没有任何一种方式适用于所有的情况。为了统一初始化方式,并且让初始化行为具有确定的效果,在C++11中提出了列表初始化的概念。
代码如下:
#include<iostream>
#include <string>
using namespace std;
class Person
{
public:
Person (int a):age(a){}
Person (int a,string b):age(a),name(b){}
int getAge()
{
return age;
}
string getName()
{
return name;
}
private:
int age;
string name;
};
int main()
{
Person p{ 23 };
cout << p.getAge() << endl;
Person p1{ 24,"Tom" };
cout << "name = " << p1.getName() << " age = " << p1.getAge() << endl;
int a{ 23 };
cout << a << endl;
int b = { 24 };
cout << b << endl;
int array[] = { 1,2,3,4,5 };
int *ptr = new int{ 250 };
cout << *ptr << endl;
int *array01 = new int[3]{ 1,2,3 };
double c = double{ 23.12 };//看起来更加直观
cout << c << endl;
return 0;
}
测试结果:
使用初始化列表初始化聚合类型的变量
聚合类型:
1.普通数组本身可以看做是一个聚合类型。
#include <iostream>
#include <string>
using namespace std;
int main()
{
int x[] = { 1,2,3,4,5 };
double y[3][3] = { {1.1,2.2,3.3},{4.4,5.5,6.6},{7.7,8.8,9.9} };
char carry[] = { 'a','b','c','d' };
string sarry[] = { "hello","world","shijie" };
return 0;
}
满足以下条件的类(class,struct,union)可以被看做是一个聚合类型:
1.无用户自定义的构造函数
2.无私有或保护的非静态数据成员
场景1:类中有私有成员,无法使用初始化列表初始化
代码如下:
struct T1
{
int x;
long y;
protected:
int z;
}t{1,100,2};//error,类中有私有成员,无法使用初始化列表初始化
场景2:类中有静态成员可以使用初始化列表,但初始化列表不能初始化静态成员变量
代码如下:
struct T2
{
int x;
long y;
protected:
static int z;
}t{1,100,2};//error
结构体中的静态变量z不能使用初始化列表进行初始化,它的初始化遵循静态成员的初始化方式。
代码如下:
struct T2
{
int x;
long y;
protected:
static int z;
}t{113,2312};
int T2::z = 3;
3.无基类
4.无虚函数
5.类中不能有使用{}和 = 直接初始化的非静态数据成员(从C++14就开始支持了)
代码如下:
#include <iostream>
using namespace std;
struct T3
{
public:
int a = 5;
int array[3]{ 1,2,3 };
int c;
};
int main()
{
T3 t{ 11,{2,3,4},12 };//从C++14开始支持了
cout << t.a << " " << t.c << endl;
for (int i = 0; i < 3; i++)
{
cout << t.array[i] << " ";
}
cout << endl;
return 0;
}
测试结果:
使用初始化列表初始化非聚合类型的对象
对于非聚合类,我们必须提供一个对应的构造函数,才能用初始化列表对其初始化。
代码如下:
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
private:
int age;
string name;
};
int main()
{
Person p{ 18,"Tom" };//error
return 0;
}
测试结果:
代码如下:
#include <iostream>
#include <string>
using namespace std;
class Person
{
public:
Person(int a,string b):age(a),name(b){}
int getAge()
{
return age;
}
string getName()
{
return name;
}
Person getPerson()
{
return { 12,"Jack" };//OK
}
private:
int age;
string name;
};
int main()
{
Person p{ 18,"Tom" };//OK
cout << p.getAge() << " " << p.getName() << endl;
return 0;
}
测试结果:
注意:
聚合类型的定义并非递归的,也就是说当一个类的非静态成员是非聚合类型时,这个类也可能是聚合类型。
代码如下:
#include <iostream>
using namespace std;
struct T1
{
int x;
double y;
private:
int z;
};
struct T2
{
T1 t1;
long x;
double y;
};
int main()
{
T2 t2{ {},520,13.14 };
return 0;
}
可以看到,T1并非一个聚合类型,因为它有一个private的非静态成员,但是尽管T2有一个非聚合类型的非静态成员t1,T2依然是一个聚合类型,可以直接使用初始化列表。
最后强调一下t2对象的初始化过程,对于非聚合类型的成员t1做初始化的时候,可以直接写一对空的{},这相当于调用是T1的无参构造函数。
以上是关于[C++11]统一的数据初始化方式 - 初始化列表的主要内容,如果未能解决你的问题,请参考以下文章
C++11新特性:19—— C++11列表初始化(统一了初始化方式)