《C++ Primer Plus》中的成员初始化列表
对于构造函数Queue::Queue(int qs):
Queue::Queue(int qs) { front = NULL;
rear = NULL; items = 0; qsize = qs; }
当qsize为常量(即const int qsize)时,上述实现无法正常运行。因为调用构造函数时,对象将在大括号中的代码执行之前被创建,亦即构造函数将先为4个成员变量分配内存,然后,程序进入到大括号中使用常规的赋值方法将值存储到内存中。对于const数据成员,必须在执行到构造函数体之前,也就是创建对象时进行初始化。通过成员初始化列表,可以实现上述工作。
成员初始化列表由逗号分割的初始化列表组成(前面带冒号),位于构造函数的参数列表之后,函数体括号之前。如果数据成员名称为mdata,且需要初始化为val,则初始化器为mdata(val),在此,初始化与赋值的区别再次体现出来。上述Queue类的构造函数以成员初始化列表语法表示如下:
Queue::Queue(int qs) : qsize(qs), front(NULL), rear(NULL), items(0) { }
对于const类成员以及被声明为引用的类成员,必须使用这种语法。这是因为引用与const数据类似,只能在被创建时进行初始化。对于简单数据成员,使用成员初始化列表和在函数体中使用赋值没有什么区别,而对于本身就是类对象的成员来说,使用成员初始化列表的效率更高,因为在构造函数体中赋值需要首先调用类对象成员的默认构造函数,然后在调用赋值运算符对其进行赋值,而成员初始化列表语法可以减少一个步骤,直接使用类对象成员的复制构造函数进行初始化。
数据成员被初始化的顺序与它们出现在类声明中的顺序相同,与初始化器中的排列顺序无关。
需要注意的是,不能将成员初始化列表语法用于构造函数之外的其他类方法。
派生类不能直接访问基类的私有成员,而必须通过基类方法进行访问,因此,派生类构造函数必须使用基类构造函数。
创建派生类对象时,程序首先创建基类对象,这意味着基类对象应当在程序进入派生类构造函数之前被创建,因此需要成员初始化列表语法,而派生类成员使用成员初始化列表语法与否均可。
RatedPlayer::RatedPlayer(unsigned int r, const string & fn, const string & ln, bool ht) : TableTennisPlayer(fn, ln, ht) { rating = r; } RatedPlayer::RatedPlayer(unsigned int r, const TableTennisPlayer & tp) : TableTennisPlayer(tp) { rating = r; }
上述代码中,第一个构造函数调用基类的构造函数(需要用初始化列表语法指明使用的基类构造函数,否则将调用默认构造函数),第二个构造函数调用基类的复制构造函数。
总之,在派生类构造函数中,首先创建基类对象,然后通过成员初始化列表将基类信息传递给基类构造函数,此外,还要对派生类新增的数据成员进行初始化。而派生类对象过期时,程序将首先调用派生类析构函数,然后再调用基类析构函数。
注:
成员初始化列表与在默认构造函数中对数据成员赋值的区别在于,如果没有成员初始化列表,则数据成员将在构造函数体之前执行默认初始化,而成员初始化列表随着构造函数体一开始执行,初始化就完成了,对于无法先定义后赋值的const或者引用类型的数据,以及属于某种未提供默认构造函数的类类型,必须通过构造函数初始值列表为这些成员提供初始值。
除此之外,由于数据成员被初始化的顺序与它们出现在类声明中的顺序相同,与初始化器中的排列顺序无关,因此最好使构造函数成员初始化列表的顺序与成员声明顺序一致,况且在允许的情况下,尽量避免使用某些成员初始化其他成员。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)