• 统一初始化(Uniform Initialization)


    原文:C++值初始化,默认初始化,以及其他初始化类型的区别?
         C++11 带来的新特性(2)-统一初始化(Uniform Initialization)
    在C++11之前,初始化没有一个统一的写法,对象的初始化方式是不同的(小括号,大括号,赋值),C++11努力创造一个统一的初始化方式,其语法是使用{}std::initializer_list。我们调用的一般形式是:

    [new] T [object] {arg1, arg2, ...};
    

    list initialization & aggregate initialization

    从简单情况来说,list initialization我们并不陌生,本质上就是:

    • 如果T是aggregate类型,list中的参数对object成员逐个初始化,若list参数个数小于T成员个数,剩余成员调用value initialization
    • 如果T不是aggregate类型,编译器查找最匹配list参数的T的构造函数。

    通过一个例子看看具体细节:

    std::vector<int> v{1, 2, 3};
    
    • 首先,参数列表{1, 2, 3}转换为std::initializer_list
      从stl的源码中可以看出initializer_list带参数的构造函数是一个私有函数,只能通过编译器调用。
        private:
          iterator          _M_array;
          size_type         _M_len;
    
          // The compiler can call a private constructor.
          constexpr initializer_list(const_iterator __a, size_type __l)
          : _M_array(__a), _M_len(__l) { }
    
    • 其次,使用std::initializer对象来初始化std::vector的构造函数。
          vector(initializer_list<value_type> __l,
             const allocator_type& __a = allocator_type())
          : _Base(__a)
          {
        _M_range_initialize(__l.begin(), __l.end(),
                    random_access_iterator_tag());
          }
    

    value initialization

    如果在list initialization行驶中,没有任何参数args,也就是:

    [new] T [object] {};
    

    值初始化一般有三种处理方式:

    • 如果T有用户定义的缺省构造函数,直接调用;
    • 如果T有编译器生成的缺省构造函数,先0值初始化再调用;
    • 如果T根本不是类,直接0值初始化。

    default initialization

    [new] T [object];
    

    缺省初始化除了在值初始化过程中可能进行之外,也可以以上面形式单独进行。这种初始化的独特地方在于,如果T是非class类型,则给出非确定值(不赋值),比如:

        int i;      //i值未定义
        int j{};    //j=0
        int *p;     //p值未定义
        int *q{};   //q=nullptr
    

    zero initialization

    0值初始化除了在值初始化过程中可能进行之外,也可以单独作用于静态(或者线程局部)变量:

    static T object;
    

    总结

    理解的要点在于,list中的参数要么按构造函数的参数声明顺序,要么按aggregate类型成员声明顺序,逐个赋值。当某些成员没有被这样显示给定值时,进行广义缺省初始化(value initialization):或调用缺省构造函数,或赋0值。

  • 相关阅读:
    JMeter使用BeanShell断言
    Django启动时找不到mysqlclient处理 django.core.exceptions.ImproperlyConfigured: Error loading MySQLdb module. Did you install mysqlclient?
    Yapi本地搭建及错误解决
    Selenium设置页面超时时间-快速终止页面加载
    Vue全套精品课笔记
    剑指offer 不用加减乘除做加法
    C++标准库函数
    剑指offer 左旋转字符串
    剑指offer 翻转单词顺序列
    剑指offer 扑克牌顺子
  • 原文地址:https://www.cnblogs.com/bloglearning/p/13901033.html
Copyright © 2020-2023  润新知