- 3
- 0
- 约2.72千字
- 约 3页
- 2017-06-08 发布于重庆
- 举报
【PRINTED】构造函数初始化列表-整理归纳注释版2015
构造函数初始化列表
以下所有程序在code::blocks中编译运行,使用GNU GCC compiler
一、什么是构造函数初始化列表
构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。例如:
class MyClass public:
MyClass :x 1 ,y 2 private:
int x;
int y;
;
MyClass :x 1 , y 2 就是构造函数初始化列表,分别将MyClass的两个成员变量x和y初始化为1和2.
以上的构造函数初始化列表跟普通的构造函数:MyClass x 1; y 2; 效果相同。
二、使用构造函数初始化列表的原因
使用构造函数初始化列表有以下两个原因:
1.必要性
(1)类中某一成员的类型是没有默认构造函数的类(或结构体)
如果类中存在这样一个成员,它的类型是没有默认构造函数(就是只有带参数的构造函数)的类或结构体,这时要对这个类成员进行初始化就只能调用这个类成员的带参数的构造函数,如果没有初始化列表,那么他将无法完成这一步。
错例:
classMyClassA public:
MyClassA int a x a; //带参数的构造函数
int x;
;
classMyClassB public:
MyClassA ca;
;
报错:error: no matching function for call toMyClassA::MyClassA |
就是说MyClassA缺少不带参数的默认构造函数MyClassA::MyClassA
为了验证,可以为MyClassA补上MyClassA ,编译通过。
还可以通过构造函数初始化列表来解决这一问题:
正确例程:
classMyClassA public:
MyClassA int a x a; //带参数的构造函数
int x;
;
classMyClassB public:
MyClassB :ca 111 ; //构造函数初始化列表
MyClassA ca;
;
这时x初始化为111.
还有以下情况需要用到构造函数初始化列表。
(2)类中含有const成员或引用类型成员
当类成员中含有const或是引用类型成员时,他们也必须要通过成员初始化列表进行初始化,因为这两种对象要在声明后马上初始化,而在构造函数中,做的是对他们的赋值,这样是不被允许的。
错误例子:
classMyClassA public:
MyClassA x 1;
const int x;
;
编译报错:
1.error: uninitialized memberMyClassA::x with const type const int|(x作为常整型变量没有经过初始化)。
2.error: assignment of read-onlydata-member MyClassA::x|(错误:构造函数中对只读变量x进行赋值操作)
要解决以上问题,可以使用初始化列表。
正确例子:
classMyClassA public:
MyClassA :x 1 ; //构造函数初始化列表
const int x;
;
对于引用型变量,亦如是。
2.效率性
类对象要通过构造函数构造,对于没有初始化列表的构造函数,进入构造函数体后进行的是赋值操作。赋值和初始化是不同的,这里存在着效率的差异,如果不用成员初始化列表,那么类对自己的类成员分别进行一次隐式的默认构造函数调用,和一次复制操作符调用,这样做效率就得不到保障。
注意:构造函数需要初始化的数据成员,不论是否出现在构造函数的成员初始化列表中,都会在该处完成初始化,并且初始化的顺序和其在声明时的顺序是一致的,与列表的先后顺序无关,所以要特别注意,保证两者顺序一致才能真正保证其效率。
程序:
#include
usingnamespace std;
classMyClassA public:
MyClassA :y 1 , x 2 ; //构造函数初始化列表
int x;
int y;
;
intmain MyClassA ca;
cout x ca.x ; y ca.y endl;
return 0; 没有errors,但是会出现warning:
MyClassA::y will be initialized after intMyClassA::x when initialized here|
可以看到,即使初始化列表中y在x前,但是,初始化时依旧按照声明时的顺序:先x后y。
再看一个很具启发性意义的程序:
#include
using
原创力文档

文档评论(0)