C++初始化函数列表详细解析

所属分类: 软件编程 / C 语言 阅读数: 100
收藏 0 赞 0 分享

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

一,需要初始化的数据成员是对象的情况;

二,需要初始化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:使用初始化列表效率更高,如果在构造函数中赋值则是拷贝,如果是初始化列表中则是初始化,赋值和初始化当然效率不一样了。

更多精彩内容其他人还在看

用标准c++实现string与各种类型之间的转换

这个类在头文件中定义, < sstream>库定义了三种类:istringstream、ostringstream和stringstream,分别用来进行流的输入、输出和输入输出操作。另外,每个类都有一个对应的宽字符集版本
收藏 0 赞 0 分享

C++如何通过ostringstream实现任意类型转string

再使用整型转string的时候感觉有点棘手,因为itoa不是标准C里面的,而且即便是有itoa,其他类型转string不是很方便。后来去网上找了一下,发现有一个好方法
收藏 0 赞 0 分享

C/C++指针小结

要搞清一个指针需要搞清指针的四方面的内容:指针的类型,指针所指向的类型,指针的值或者叫指针所指向的内存区,还有指针本身所占据的内存区
收藏 0 赞 0 分享

C++ 类的静态成员深入解析

在C++中类的静态成员变量和静态成员函数是个容易出错的地方,本文先通过几个例子来总结静态成员变量和成员函数使用规则,再给出一个实例来加深印象
收藏 0 赞 0 分享

C++类的静态成员初始化详细讲解

通常静态数据成员在类声明中声明,在包含类方法的文件中初始化.初始化时使用作用域操作符来指出静态成员所属的类.但如果静态成员是整型或是枚举型const,则可以在类声明中初始化
收藏 0 赞 0 分享

C++类静态成员与类静态成员函数详解

静态成员不可在类体内进行赋值,因为它是被所有该类的对象所共享的。你在一个对象里给它赋值,其他对象里的该成员也会发生变化。为了避免混乱,所以不可在类体内进行赋值
收藏 0 赞 0 分享

C++中的friend友元函数详细解析

友元可以是一个函数,该函数被称为友元函数;友元也可以是一个类,该类被称为友元类。友元函数的特点是能够访问类中的私有成员的非成员函数。友元函数从语法上看,它与普通函数一样,即在定义上和调用上与普通函数一样
收藏 0 赞 0 分享

static全局变量与普通的全局变量的区别详细解析

以下是对static全局变量与普通的全局变量的区别进行了详细的分析介绍,需要的朋友可以过来参考下,希望对大家有所帮助
收藏 0 赞 0 分享

C++ explicit关键字的应用方法详细讲解

C++ explicit关键字用来修饰类的构造函数,表明该构造函数是显式的,既然有"显式"那么必然就有"隐式",那么什么是显示而什么又是隐式的呢?下面就让我们一起来看看这方面的知识吧
收藏 0 赞 0 分享

教你5分钟轻松搞定内存字节对齐

随便google一下,人家就可以跟你解释的,一大堆的道理,我们没怎么多时间,讨论为何要对齐.直入主题,怎么判断内存对齐规则,sizeof的结果怎么来的,请牢记以下3条原则
收藏 0 赞 0 分享
查看更多