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

时间: 2024-11-08 09:18:22

c++初始化函数列表的相关文章

gcc attribute 初始化函数列表

gcc的__attribute__编译属性有很多子项,用于改变作用对象的特性.这里讨论section子项的作用. __attribute__的section子项使用方式为: ? 1 __attribute__((section("section_name"))) 其作用是将作用的函数或数据放入指定名为"section_name"的段. 看以下程序片段: ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 2

虚函数列表: 取出方法 // 虚函数工作原理和(虚)继承类的内存占用大小计算 32位机器上 sizeof(void *) // 4byte

#include <iostream> using namespace std; class A { public: A(){} virtual void geta(){ cout << "A:A" <<endl; } virtual void getb(){ cout << "A:B" <<endl; } }; class B :public A{ public: B(){} virtual void g

GCC中初始化函数是如何被处理的?

本文译至: http://gcc.gnu.org/onlinedocs/gccint/Initialization.html 如我们所知,在GCC通过给代码追加__attribute__((constructor))和__attribute__((destructor))的方式可以追加初始函数和终止函数, 这篇文章介绍了GCC内部是如何实现上述处理的. 简单的说,就是在最经常的情况下,初始函数会被追加到.ctor section中,.init会调用对应的函数处理这些初始函数.终止情况类似. --

8.1.4 在 F# 中使用函数列表

首先,我们声明一个表示有关客户信息的类型:客户有很多属性,因此,用F# 的记录类型表示最自然的选择,我们在前一章已经看过.清单 8.4 显示了类型声明,和所创建样本客户的代码. 清单 8.4 Client 记录类型和样本值 (F# Interactive) > type Client = { Name : string; Income : int;YearsInJob : int UsesCreditCard : bool;CriminalRecord : bool };; type Clien

GCC中初始化函数是怎样被处理的?

本文译至: http://gcc.gnu.org/onlinedocs/gccint/Initialization.html 如我们所知,在GCC通过给代码追加__attribute__((constructor))和__attribute__((destructor))的方式能够追加初始函数和终止函数, 这篇文章介绍了GCC内部是怎样实现上述处理的. 简单的说,就是在最常常的情况下,初始函数会被追加到.ctor section中,.init会调用相应的函数处理这些初始函数.终止情况类似. --

LoadRunner中的Web 函数列表

web test LoadRunner fuction_list D:\Program Files (x86)\Mercury Interactive\Mercury LoadRunner\bin>ls -l *.chm -rw-rw-rw-   1 user     group       25893 May 20  2004 FuncRef.chm -rw-rw-rw-   1 user     group       29443 May 20  2004 RPM_Configuration

iOS: 聊聊 Designated Initializer(指定初始化函数)

iOS: 聊聊 Designated Initializer(指定初始化函数) 一.iOS的对象创建和初始化 iOS 中对象创建是分两步完成: 分配内存 初始化对象的成员变量 我们最熟悉的创建NSObject对象的过程: 苹果官方有一副图片更生动的描述了这个过程: 对象的初始化是一个很重要的过程,通常在初始化的时候我们会支持成员变量的初始状态,创建关联的对象等.例如对于如下对象: 1 @interface ViewController : UIViewController 2 3 @end 4

OC语言中的便利初始化函数和便利构造器

便利遍历初始化函数与便利构造器(以Student类为例): main函数 Student.h(声明) ................... Student.m(实现) .................

正试图在 os 加载程序锁内执行托管代码。不要尝试在 DllMain 或映像初始化函数内运行托管代码

当我在窗体初始化的时候,调用了一个外部的dll,它就不知什么原因的 抛出一个“正试图在 os 加载程序锁内执行托管代码.不要尝试在 DllMain 或映像初始化函数内运行托管代码”的异常,程序就卡掉了,在网上查了查,相关说明如下: .NET2.0中增加了42种非常强大的调试助手,MDA.Loaderlock 是其中之一.Loaderlock检测在一个拥有操作系统loader lock的线程上运行托管代码的情况.这样做有可能会引起死锁,并且有可能在操作系统加载器初始化DLL前被使用. 大致理解:就