当前位置:   article > 正文

C++ 语法之【成员初始化列表】

成员初始化列表

类对象构造过程

《C++ Primer Plus》中这样描述:从概念上来说,调用构造函数时,对象将在括号中的代码被执行之前被创建。因此,调用构造函数将导致程序先给其成员变量分配内存。然后,程序流程进入到括号中,使用常规的赋值方式将值存储到内存中

我们将构造函数分为两个先后过程

1.初始化阶段。创建对象,给成员变量分配内存。调用构造函数时,创建对象,隐式/显示的初始化各数据成员(给其成员变量分配内存);

2.赋值计算阶段。进入构造函数体中执行一般赋值与计算操作。

定义【成员初始化列表】

与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段。
成员初始化列表只能在构造函数中使用。

必须使用【成员初始化列表】的情况

情况一:const类成员或者被声明为引用的类成员

对于类成员中含有一个const(常量)对象时,或者是一个引用时,他们也必须要通过成员初始化列表进行初始化。

因为这两种对象要在声明后马上初始化,而在构造函数中,做的是对他们的赋值,这样是不被允许的。所以必须在执行到构造函数体之前,即在对象被创建时进行初始化。

class A
{
 priate:
    const int a;            //const修饰成员
 public:
    A():a(10){}             //初始化
};

class B
{
 private:
     int &b;                //被声明为引用
 public:
     B(int b):b(b){}     //初始化
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

情况二:初始化成员是对象(包含继承)

如果一个类成员本身就是一个类或者一个结构,并且这个成员只有一个带参数的构造函数,没有无参数的构造函数;这时要对这个类成员进行初始化,就必须调用这个类成员的带参数的构造函数,如果没有初始化列表,那么他将无法完成第一步,就会报错。

class A
{
 public:
    A (int, int){
 };
 private:	//类成员为x,y
    int x;
    int y;
};
class B 
{
 public:
    B():a(1,2),z(z){       //初始化
    };
private:
    A a; //B的另一个类成员为一个A的类对象, 类对象作为类成员
   	int z;
};
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

情况三:子类初始化父类的私有成员

子类初始化父类的私有成员,需要在(并且也只能在)参数初始化列表中显示调用父类的构造函数。

class Test{
public:
    Test(){};
    Test (int x){ int_x = x;};
    void show(){cout<< int_x << endl;}
private:
    int int_x;
};
class Mytest:public Test{
public:
    Mytest()Test(110){
      //Test(110);            //  构造函数只能在初始化列表中被显示调用,不能在构造函数内部被显示调用
    };
};
int main()
{
 Test *p = new Mytest();
 p->show();
 return 0;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

必须使用【初始化列表】的原因

其一:C++语法规定使然。
其二:主要是性能问题,对于内置类型,如int, float等,使用初始化类表和在构造函数体内初始化差别不是很大,但是对于类类型来说,最好使用初始化列表。

为什么呢?
使用初始化列表少了一次调用默认构造函数的过程,这对于数据密集型的类来说,是非常高效的。

所以一个好的原则是,能使用初始化列表的时候尽量使用初始化列表.

初始化顺序问题

数据成员被初始化的顺序与他们出现在类声明中的顺序相同,与初始化器中的排列顺序无关。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/209084
推荐阅读
相关标签
  

闽ICP备14008679号