C++ 中的初始化列表

原文:https://www.studytonight.com/cpp/initializer-list-in-cpp.php

初始化列表用于初始化数据成员。语法以冒号(:)开头,然后用逗号分隔每个变量及其值。初始值设定项列表不以分号结束。

语法:

Constructorname(datatype value1, datatype value2):datamember(value1),datamember(value2)
{
    ...
}

例如:

#include<iostream>
using namespace std;

class Base
{
    private:
    int value;
    public:
    // default constructor
    Base(int value):value(value)
    {
        cout << "Value is " << value;
    }
};

int main()
{
    Base il(10);
    return 0;
}

值为 10

上面的代码只是一个理解 Initializer 列表语法的例子。在上面的代码中,value也可以很容易地在构造器内部初始化,因此我们不必使用初始化列表。


C++ 中初始化列表的使用

有些情况下,构造器内部的数据成员初始化不起作用,必须使用初始化列表。以下是这种情况:

1)当没有基类默认构造器时

在继承中,基类构造器首先被调用(构造器调用的顺序),然后是子类构造器。

因此,在下面的例子中Base_类构造器将在InitilizerList_类构造器之前被调用,因此下面的程序将抛出编译错误:“基类不存在默认构造器”。

#include<iostream>
using namespace std;

class Base_
{
    public:
    // parameterized constructor
    Base_(int x)
    {
        cout << "Base Class Constructor. Value is: " << x << endl;
    }
};

class InitilizerList_:public Base_
{
    public:
    // default constructor
    InitilizerList_()
    {
        Base_ b(10);
        cout << "InitilizerList_'s Constructor" << endl;
    }
};

int main()
{
    InitilizerList_ il;
    return 0;
}

上面的代码示例可以使用初始化列表重写,并且会顺利执行,没有任何错误。

以下是新代码:

#include<iostream>
using namespace std;

class Base_
{
    public:
    // parameterized constructor
    Base_(int x)
    {
        cout << "Base Class Constructor. Value is: " << x << endl;
    }
};

class InitilizerList_:public Base_
{
    public:
    // default constructor using initializer list
    InitilizerList_():Base_(10)
    {
        cout << "InitilizerList_'s Constructor" << endl;
    }
};

int main()
{
    InitilizerList_ il;
    return 0;
}

基类构造器的值是 10 InitilizerList _ 的构造器


2)当使用引用类型时

如果有数据成员作为引用类型,则必须在初始化列表中对其进行初始化。引用是不可变的,因此只能初始化一次。

#include<iostream>
using namespace std;

class Base
{
    private:
    int &ref;
    public:
    Base(int &ref):ref(ref)
    {
        cout << "Value is " << ref;
    }
};

int main()
{
    int ref=10;
    Base il(ref);
    return 0;
}

值为 10


3)用于初始化const数据成员

const数据成员只能初始化一次,因此必须在初始化列表中进行初始化。

#include<iostream>
using namespace std;

class Base
{
    private:
    const int c_var;
    public:
    Base(int c_var):c_var(c_var)
    {
        cout << "Value is " << c_var;
    }
};

int main()
{
    Base il(10);
}

值为 10


4)当数据成员和参数同名时

#include<iostream>
using namespace std;

class Base
{
    private:
    int value;
    public:
    Base(int value):value(value)
    {
        cout << "Value is " << value;
    }
};

int main()
{
    Base il(10);
    return 0;
}

值为 10


5)为了提高性能

如果在构造器体内部赋值,那么将创建一个临时对象,提供给赋值运算符。临时对象将在赋值语句结束时被销毁。使用初始化列表可以避免创建临时对象。