C++初始化函数列表详细解析
在以下三种情况下需要使用初始化成员列表:
一,需要初始化的数据成员是对象的情况;
二,需要初始化const修饰的类成员;
三,需要初始化引用成员数据;
原因:
C++可以定义引用类型的成员变量,引用类型的成员变量必须在构造函数的初始化列表中进行初始化。对于类成员是const修饰,或是引用类型的情况,是不允许赋值操作的,(显然嘛,const就是防止被错误赋值的,引用类型必须定义赋值在一起),因此只能用初始化列表对齐进行初始化。成员类型是没有默认构造函数的类。若没有提供显示初始化式,则编译器隐式使用成员类型的默认构造函数,若类没有默认构造函数,则编译器尝试使用默认构造函数将会失败。(也就是这三种情况必须使用初始化列表)
我们定义一个如下的Person类:
class Person {
public:
Person() { } //default constructor function
Person(string name, string phone, string addr)
{
m_name = name; //想采用赋值初始化数据成员
m_phone = phone;
m_addr = addr;
}
private:
const string m_name;
const string m_phone;
const string m_addr;
};
编译后发现这个类的第二个带参数的构造函数是错误的。我们创建一个Person对象:
Person p("marcky", "13233232", "cqupt"); //调用带参数的构造函数创建一个Person对象 创建对象的过程分为了两步:
一、从内存中分配实际的空间给对象p,其三个字符串对象的数据成员是调用的默认构造函数初始化为空。也就说,此时为止,对象p的三个数据成员都是一个空的字符串。
二、执行调用的构造函数的函数体语句,完成对数据成员的赋值,以此达到我们期望的创建一个指定Person对象,而不是空对象。
从上面的第二步就可以看到,我们在对三个const对象进行赋值操作,这显然是不允许的操作,因此利用这个构造函数创建Person将以失败告终。要想成功的创建一个特定的Person对象,我们需要构造函数初始化列表:
Person(string name, string phone, string addr)
:m_name(name), m_phone(phone), m_addr(addr){ } //冒号开始定义初始化列表 使用初始化列表创建对象的构造函数同样是通过上述的两个步骤来完成的,不同之处在于创建对象的数据成员时使用的不是默认构造函数,而是根据指定参数调用了相应的构造函数,以此创建特定的对象,而不是空对象。这样一来,对象的数据成员的特定值在创建对象的时候就被赋予了相应的成员,而不是在创建对象完成之后再通过赋值语句去修改数据成员,因此利用构造函数初始化列表就可以成功的创建具有const数据成员的对对象了。
没有默认构造函数的类类型成员,如果不在初始化列表中初始化的话,那么创建该对象的时候,由于没有指定相应的“实参”,编译器就会去调用默认构造函数来创建对象,必然会以失败而告终。
注1:数据成员被初始化的顺序与构造函数初始化列表中的次序无关,而是与成员的定义顺序一致。
注2:使用初始化列表效率更高,如果在构造函数中赋值则是拷贝,如果是初始化列表中则是初始化,赋值和初始化当然效率不一样了。
您可能感兴趣的文章:
- 成员初始化列表与构造函数体中的区别详细解析
- Python数据结构(列表、字典、集合、元组)详细解析
- ExpandableListView可展开的列表组件详细解析
- Python数据结构(列表、字典、集合、元组)详细解析
- C++初始化函数列表详细解析
- 【OSC手机App技术解析】- 气泡对话列表
- HTTP之I/O模型图MPM详细解析
- mysql日志详细解析
- AndroidFramework之Volley详细解析 定制Request (三)
- Hash散列算法详细解析(六)
- 详细解析C++中new的三种用法
- 详细解析Java中抽象类和接口的区别
- 发布iOS应用(Xcode5)到App Store详细解析
- thrift之TTransport类体系原理及源码详细解析1-类结构和抽象基类
- 计算机端口介绍详细列表
- python整理十——生成器表达式与列表解析
- 二十一、详细解析Java中抽象类和接口的区别
- 乘法口诀表可以这样打印——使用列表解析创建矩阵
- Java 集合系列05之 LinkedList详细介绍(源码解析)和使用示例
- Three20 NetWork 源码详细解析