CPP11-初始化列表

在CPP11之前的不同对象都有各自的初始化方式,于是初始化列表特性的目的在于统一初始化环节

统一初始化

提供了基本类型、数组、自定义类型等不同对象的初始化

class Student
{
public:
    Student(string name, int age) 
        : m_name(name), m_age(age) {
        cout << __FUNCTION__ << endl;
    }
private:
    string m_name;
    int m_age;
};

Student s1("Jeson", 18);    // 传统方式
Student s2{ "Mark", 18 };   // 初始化列表

int a1 {10};
int a2 = {10};
int * arr = new int[4]{ 0, 2, 4, 5 };

<font color=red>注意事项:自定义类型是尽量实现对应的构造函数,虽然初始化列表支持使用默认构造按照声明顺序进行初始化,但是从开发规范的角度来说,这种方式容易产生隐藏bug,不易排查</font>

struct Student
{
    string m_name;
    int m_age;
};

Student s1{ "Jeson", 18 };    // 编译通过; s1.m_name == Jeson ; s1.m_age == 18
Student s2{ 18, "Jeson" };    // 编译不通过

类型安全

初始化列表可以防止"缩窄"的隐式类型转换,对于小到大的则不做限制

int a1 = 3.14;   // 编译通过
int a2 = {3.14}; // 编译不过,vs2017报错(error C2397: 从“double”转换到“int”需要收缩转换)

double b1 = 3;   // 编译通过
double b2 = {3}; // 编译通过

初始化模板类-std::initializer_list

cpp11提供了std::initializer_list模板类,可将其作为构造函数的参数,如果类有接受initializer_list作为参数的构造函数,则初始化列表语法就只能用于该构造函数。

class A
{
public:
    A(std::initializer_list<int> list) {
        cout << "A(std::initializer_list<int> list)" << endl;
    }
    A(int a, int b) {
        cout << "A(int a, int b)" << endl;
    }
};

A a1{ 1, 2 };    // A(std::initializer_list<int> list)
A a2(1, 2);      // A(int a, int b)

参考

  • 《C++ Primer Plus(第6版)中文版》
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • C++11新增了列表初始化的概念。 在C++11中可以直接在变量名后面加上初始化列表来进行对象的初始化。 列表初始...
    this_is_for_u阅读 480评论 0 0
  • 有朋友在使用std::array时发现一个奇怪的问题:当元素类型是复合类型时,编译通不过。 struct S { ...
    金色888阅读 427评论 0 0
  • 标准模板库中容器对初始化列表的支持源自 这个头文件中initialize_list类模板的支持。程序员只要#inc...
    i_need_job阅读 90评论 0 1
  • 1 初始化列表 C++98/03中可以使用初始化列表对普通数组、POD类型等进行初始化。如: 但是这种初始化方式的...
    georgeguo阅读 1,420评论 0 1
  • 对于类对象的初始化,可以使用传统的构造方式(使用圆括号),也可以使用列表初始化(使用花括号)。 假设有如下类的定义...
    shelldon1024阅读 195评论 0 0