C++11使用{}大括号初始化

在C++11中,使用{}可进行如下各项的初始化:

  • 类成员快速初始化
  • 数组、集合(列表)初始化
  • 自定义类型初始化

C++11可以将{}初始化器用于任何类型(可以使用等号,也可以不适用),这是一种通用的初始化语法。

集合、函数

在C++11中,集合(列表)的初始化已经成为C++的一个基本功能,被称为“初始化列表(initializer list)”

示例代码:

int a[] = { 1, 2, 3 };            //C++98支持,C++11支持
    int b[]{2, 3, 4};                //C++98不支持,C++11支持
    vector<int> c{ 1, 2, 3 };        //C++98不支持,C++11支持
    map<int, float> d = {{ 1, 1.0f }, { 2, 2.0f }, { 3, 3.0f } };//C++98不支持,C++11支持

在C++11中,自动变量和全局变量的初始化方式包括:

  • 等号=加上赋值表达式(assignment-expression),例如:int a=2+3;
  • 等号=加上花括号表达式的初始化列表,例如:int a = {3+4};
  • 圆括号式的表达式列表(expression-lit),例如:int a(6+8);
  • 花括号式的初始化列表:例如:int a{6+8};

最后两种形式也可以用于获取堆内存new操作符中,例如:

int* i = new int(1);
    double* d = new double(1.2f);

C++11使用{}大括号初始化

标准模板库STL中容器对初始化列表的支持源于头文件中initialize_list类模板的支持。程序员只要#include并声明一个以initialize_List模板类为参数的构造函数,也可以使得自定义类使用列表初始化。

enum Gender{ boy, girl };
class People
{
public:
    //initializer_list的构造函数
    People(initializer_list<pair<string, Gender>> ll)
    {
        auto iter = ll.begin();
        for (; iter != ll.end(); ++iter)
        {
            data.push_back(*iter);
        }
    }
private:
    vector<pair<string, Gender>> data;
};

//函数的参数列表使用初始化列表
void Fun(initializer_list<int> iv){}

上述代码中,为People类定义了一个使用initializer_list>模板类作为参数的构造函数,使用C++11的auto关键字来自动类型推断。

可以使用{}以如下的方式初始化:

People people = { { "Garfield", boy }, { "HelloKitty", girl } };

上述代码也定义了一个使用initializer_list为参数的函数,也可以使用初始化列表:

Fun({ 1, 2 });
    Fun({});//空列表

同理,类和结构体的成员函数也可以使用初始化列表,包括一些操作符的重载函数。示例代码:

class Mydata
{
public:
    Mydata & operator[] (initializer_list<int> input)
    {
        for (auto i = input.begin(); i != input.end(); ++i)
        {
            idx.push_back(*i);
        }
        return *this;
    }
    Mydata & operator = (int v)
    {
        if (idx.empty() != true)
        {
            for (auto i = idx.begin(); i != idx.end(); ++i)
            {
                d.resize((*i > d.size()) ? *i : d.size());
                d[*i - 1] = v;
            }
            idx.clear();
        }
        return *this;
    }
    void print()
    {
        for (auto i = d.begin(); i != d.end(); ++i)
        {
            cout << *i << " ";
        }
        cout << endl;
    }

private:
    vector<int> idx;//辅助数组,用于记录index
    vector<int> d;
};

Mydata mydata;

mydata[{2, 3, 5}] = 7;

mydata[{1, 4, 5, 8}] = 4;

mydata.print();


C++11使用{}大括号初始化

另外,初始化列表页可以用于函数返回的情况,与声明时使用列表初始化一样,列表初始化构造成什么类型是依据返回类型的:

vector<int> Func() { return{ 1, 3 }; }

类成员初始化

C++98中,对于类中的静态成员常量,可以使用等号“=”加初始值的方式进行初始化,称为“就地”声明。在C++98中要求较高:如果静态成员不满足常量性,不能就地声明,且而且即使常量的静态成员也只能是整型或枚举型才能就地初始化。

C++11使用{}大括号初始化

在C++11中,除了初始化列表(在构造函数中初始化)外,允许使用等=或花括号{}进行就地的非静态成员变量初始化,例如:

struct example
{
    int a = 1;
    double b{ 1.2 };
};

注意:

如果在一个类中,既使用了就地初始化来初始化非静态成员变量,又在构造函数中使用了初始化列表,执行顺序是:先执行就地初始化,然后执行初始化列表。

注意执行顺序可能导致的问题。

参考:

《深入理解C++11》

《C++ Primer Plus 6th》
原文链接: https://www.cnblogs.com/zyk1113/p/13452493.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/201191

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月12日 下午8:42
下一篇 2023年2月12日 下午8:42

相关推荐