C++11之初始化列表

简介: C++11之初始化列表

初始化列表

C++98之初始化列表

其实在初始化列表这个词并不陌生,早在C++98中就已经引入了。可以通过{}一对大括号对数组元素进行统一的初始值设定。

如:int a{2}; int arr[] = {1,5,2};

但是这种方式初始化仅仅支持内置类型,也就是说结构体类型,容器都是不支持的。


例如下面这段代码,可以看到只有数组a能被正常初始化。

C++11之初始化列表

在C++11标准中,又对初始化列表的功能进行一次强化。


初始化列表前有无=等号作用相同,例如下面几种写法都是正确的。

1 int a = {5 + 5};

2 int a{2+1};

3 int a{3+1};

4 int* p = new int(1);

5 int* p = new int{9};


initializer_list模板类

用于对象的初始化

initializer_list是C++11提供的新类型,定义在头文件中。用于表示某种特定类型的值的数组,和vector一样,initializer_list是一种模板类型。

#include <iostream>
#include <vector>
#include <initializer_list>
using namespace std;
class A
{
public:
  A(int a, int b){}
};
enum class Gender
{
  boy = 1,
  girl = 2,
};
class People
{
public:
  People(initializer_list<pair<string, Gender>> l)
  {
    initializer_list<pair<string, Gender>>::const_iterator iter = l.begin();
    for(; iter != l.end(); ++iter)
    {
      data.push_back(*iter);
    }
  }
private:
  vector<pair<string, Gender>> data;
};
int main()
{
  People pp = { {"aa", Gender::boy}, {"bb", Gender::girl} };
  return 0;
}


在上面的代码中,为这个类提供了一个initializer_list<pair<string, Gender>>模板版本的构造函数。这样就可以采用通过初始化列表的方式进行初始化了。


用于函数参数的初始化

initializer_list除了可以初始化还可以作为函数的参数列表,就可以让函数支持初始化列表。

#include <iostream>
#include <vector>
#include <initializer_list>
using namespace std;
void test(initializer_list<int> iv){}
int main()
{
  test({ 1,5,3,99 });
  test({ 1 });
  return 0;
}


在上面这个例子中,定义了一个接受初始化列表的函数test。这种方法不局限于全局函数,成员函数也是可以的。

用于重载运算符

initializer_list还可以用在重载下标运算符中operator[]。


下面这个例子稍微复杂一点,但正因为复杂也能体现出初始化列表的便捷性。


创建了一个类A,其中重载了下标运算符,赋值运算符。实现了一个可以通过下标运算符[]来对数组内的值进行批量初始化。


1.重载下标运算符的目的是将需要初始化的下表进行一个记录,以便后续的初始化工作。

2.重载赋值运算符的目的是将之前记录的所有需要初始化的索引进行一个循环初始化工作。


#include <iostream>
#include <vector>
#include <initializer_list>
using namespace std;
class A
{
public:
  /*
   *  用于记录需要初始化的下表
   */
  A& operator[](initializer_list<int> l)
  {
    for(initializer_list<int>::const_iterator iter = l.begin(); iter != l.end(); ++iter)
    {
      index.push_back(*iter);
    }
    return *this;
  }
  /*
   *  用于将之前index提前保存好的下表进行统一初始化
   */
  A& operator=(int v)
  {
    if(false == index.empty())
    {
      for (vector<int>::const_iterator iter = index.begin(); iter != index.end(); ++iter)
      {
        if (d.size() < *iter)
        {
          d.resize(*iter);
        }
        d.at(*iter - 1) = v;
      }
      index.clear();
      return *this;
    }
  }
  void Print()
  {
    for(const auto elem : d)
    {
      cout << elem << " ";
    }
    cout << endl;
  }
private:
  vector<int> index; // 辅助数组,用于记录index
  vector<int> d; 
};
int main()
{
  A a;
  a[{1, 5, 8, 4}] = 1;
  a.Print();
  a[{2, 1, 6, 9, 4}] = 6;
  a.Print();
  return 0;
}

可以看到我们自定义批量初始化仅需要一行即可完成a[{1, 5, 8, 4}] = 1;。可见初始化的灵活性、强大性。


目录
相关文章
|
1月前
|
存储 编译器 C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(一)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
2月前
|
编译器 C++
C++ 类构造函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。
73 30
|
1月前
|
存储 编译器 数据安全/隐私保护
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解2
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
29 3
|
1月前
|
编译器 C++
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解1
【C++篇】C++类与对象深度解析(四):初始化列表、类型转换与static成员详解
44 3
|
1月前
|
C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(二)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
1月前
|
编译器 C++
【C++】深入探索类和对象:初始化列表及其static成员与友元(三)
【C++】深入探索类和对象:初始化列表及其static成员与友元
|
1月前
|
C++
C++构造函数初始化类对象
C++构造函数初始化类对象
17 0
|
3月前
|
Dart API 开发工具
Dart ffi 使用问题之Dart API要在C++中使用,该如何初始化
Dart ffi 使用问题之Dart API要在C++中使用,该如何初始化
|
4月前
|
编译器 C++
【C++】详解初始化列表,隐式类型转化,类静态成员,友元
【C++】详解初始化列表,隐式类型转化,类静态成员,友元
|
5月前
|
存储 编译器 C++
【C++】类和对象④(再谈构造函数:初始化列表,隐式类型转换,缺省值
C++中的隐式类型转换在变量赋值和函数调用中常见,如`double`转`int`。取引用时,须用`const`以防修改临时变量,如`const int& b = a;`。类可以有隐式单参构造,使`A aa2 = 1;`合法,但`explicit`关键字可阻止这种转换。C++11起,成员变量可设默认值,如`int _b1 = 1;`。博客探讨构造函数、初始化列表及编译器优化,关注更多C++特性。