C++构造函数的初始化列表

  • 构造函数的初始化列表

当一个类的成员变量是另一个类的对象时
例:

#include
using namespace std;

class A{
public:
A()
{
	cout<<"A()"<x=x;
   cout<<"A(int x)"<

在生成一个B的对象 B b时,如何初始化成员变量a呢?

我们知道构造函数是给对象的内存进行初始化,那么在初始化对象b的内存中a所占的内存时,应该调用类A的构造函数给a的内存进行初始化

如果将类B的构造函数定义为:

B(int x)
{
	this->a=A(x);
}

运行提示:

C++构造函数的初始化列表_第1张图片

我们的预想是用x生成的临时对象A(x)去直接生成对象b的成员变量a,应该只有A(int x)这个构造函数调用

但结果却是调用A()、A(int x)、A& operator(const A &rhs)

那我们就必须清楚初始化和赋值两者的区别:

1)初始化:一个变量或者一个对象在产生的时候就赋予一个值,属于伴随性质

2)赋值:在一个变量或者一个对象在产生之后的任意时刻赋予一个值,属于任意性质

很明显,构造函数函数体内的语句是赋值语句,而并非初始化语句

在this->a=A(x)这条语句中,A(x)调用A(int x),     this->a=A(x);调用A& operator(const A &rhs)

那么 A()这个函数应该在构造函数B(int x)运行前就被调用。

那么我们如何直接利用临时对象A(x)去直接生成对象b的成员变量a呢?

   那就利用到了构造函数的初始化列表

  它的作用:对数据成员进行初始化

构造函数的初始化列表格式:构造函数():变量名1(数值),变量名2(数值)

例:

B(int x):a(x)
{	
}

将成员对象a放在构造函数的初始化列表中,运行结果:

从结果可知,在初始化列表中的变量直接初始化,而并非赋值。

初始化列表的特点:

1)在构造函数执行时,先执行初始化列表,实现变量的初始化,然后再执行构造函数内部的语句进行赋值操作。

例:

#include
using namespace std;

class A{
public:
  A(int a,int b,int c):x(a),y(b),z(c)
{
   cout<<"A(int a,int b,int c)"<

运行结果:

2)成员初始化的顺序只与声明的顺序有关,而跟初始化列表的顺序无关。例如在上面的代码中类A的构造函数初始化列表中,我们写成:z(x),y(x), x(a),但是我们还是先初始化变量x,然后y,然后z,因为我们先声明的变量a,然后b,然后c

例:

#include
using namespace std;

class A{
public:
  A(int a,int b,int c):y(x),z(x),x(a)
{
   cout<<"A(int a,int b,int c)"<

运行结果:

C++构造函数的初始化列表_第2张图片

如果按照初始化列表中y(x),z(x),x(a)的顺序进行初始化,结果应该为x=1,y=0xcccccccc,z=0xcccccccc.

但我们从运行结果可以看出,x,y,z的值都为1,那么它初始化的顺序就不按照初始化列表的顺序进行初始化,

而根据变量的声明顺序进行初始化。

3)成员之间可以相互初始化:a(12), b(a)  //a,b为相同类型的话

从上面代码y(x),z(x),x(a)就可以看出。

 

从上面的代码我们可以看出,内置类型的变量可以在构造函数的函数体内进行赋值,可以直接在构造函数的初始化列表中直接初始化,那么什么样的数据必须放到构造函数的初始化列表中呢?

1)const修饰的成员变量。

我们知道,在C++中const修饰的变量称之为常量,它一定要初始化,并且常量是不能进行修改的,

而构造函数的函数体内语句是进行赋值操作,如果将const修饰的成员变量的放到构造函数的函数体内进行赋值,

这就明显修改常量内存块的值,代码错误。

2)引用类型的成员变量。

我们知道,在C++中引用一定要初始化,并且引用不能修改,

如果放到构造函数的函数体内进行赋值,修改引用所引用的变量,代码错误。

你可能感兴趣的:(C++)