zl程序教程

您现在的位置是:首页 >  .Net

当前栏目

C++笔记(7)成员初始化列表

2023-02-18 16:27:15 时间

  成员初始化列表由逗号分隔的初始化列表组成(前面带冒号),它位于参数列调的右括号之后,函数体左括号之前。如果数据成员的名称为mdata,并需要将它初始化为val,则初始化器为mdata(val).

Classy::Classy(int val) : mdata(val)

以下三种情况下需要使用初始化成员列表: 

1.  需要初始化const修饰的类成员或初始化引用成员数据;

2. 需要初始化的数据成员是对象的情况(这里包含了继承情况下,通过显示调用父类的构造函数对父类数据成员进行初始化); 

3. 子类初始化父类的私有成员;

 

1. 需要初始化const修饰的类成员或初始化引用成员数据

1)初始化const修饰的类成员

下面为一个队列类,

class Queue
{
private:
    struct Node {Item item; struct Node* next;};
    enum { Q_size = 10 };
    Node* front;
    Node* rear;
    int items;
    const int qsize;
public:
    Queue(int qs = Q_size);
    ~Queue();
};

应该将队列的最大长度qsize设置为构造函数参数qs的值。

下面的实现方法无法正常运行:

Queue::Queue(int qs)
{
    front = rear = nullptr;
    items = 0;
    qsize = qs;
}

这是由于,在调用构造函数时,首先会给成员变量开辟内存,然后通过常规赋值将值存储到内存中。而qsize是常量,可以对它进行初始化,但不能给它赋值。因此,对于const数据成员,必须在执行到构造函数体之前,即创建对象时进行初始化。

使用成员初始化列表,可以这样编写Queue的构造函数:

Queue::Queue(int qs) : qsize(qs)
{
    front = rear = nullptr;
    items = 0;
}

通常,初值可以是常量或构造函数的参数列表中的参数。这种方法并不限于初始化常量,可以将Queue的构造函数写成如下所示:

Queue::Queue(int qs) :qsize(qs), front(nullptr), rear(nullptr), items(0)
{
}

2)初始化引用成员数据

对于被声明为引用的类成员,也必须使用这种语法:

class Agency{...};
class Agent
{
private:
    Agency & belong;
    ...
};
Agent::Agent(Agency & a) : belong(a){...}

这是因为引用和const数据类似,只能在被创建时进行初始化。对于简单数据成员(例如front和items),使用成员初始化列表和在函数体中赋值没有什么区别。然而,对于本身就是类对象的成员来说,使用成员初始化列表的效率更高。

 

 

 

参考:1.《c++ primer plus》p378

2. https://blog.csdn.net/sinat_20265495/article/details/53670644