您的位置:首页 > 编程语言 > C语言/C++

C++(笔记)子类构造器初始化&执行顺序问题

2017-04-19 16:58 113 查看

一、子类中的构造器

(一).关于初始化问题

 1.对子类新增成员进行初始化,必须添加子类的构造器

 2.对基类成员初始化,必须是基类构造器完成(因为基类数据成员一般继承都是private,子类对它不能有所作为),这一点必须明白!

(二).关于如何初始化

当使用子类就要用到子类的对象,但对象必须初始化(包括默认构造器来初始化),那么问题来了!!初始化是对子类的所以数据成员初始化(这里要明白,子类所以成员指的是基类继承下来的和子类自己新增的成员)

重点来了!:既然必须要初始化,那么如何初始化呢?

因为基类的构造器和析构器并没有继承到子类中,所以就需要子类创建带参构造器,利用初始化列表用基类构造器对基类数据成员初始化,而另一些参数来对子类新成员初始化(没有上述带参构造器的话就会调用默认的无参构造器哦)

(三).初始化后的执行顺序(与子类初始化列表里书写顺序无关)

1.先调用基类构造器,初始化基类成员

2.再找初始化列表指定的初始化子类新成员对象

3.最后才执行子类构造器中的函数体

(四).何时需要声明子类构造器

很简单,当你需要调用基类带有形参表的构造器时,这一点还得自己学会观察看需求!

二、代码解决问题(基类构造器,子类构造器,析构器调用顺序)

#include <iostream>
using namespace std;

class Base1{
public:
Base1(int i)
{
cout<<"调用Base1带参构造器:"<<i<<endl;
}

~Base1()
{
cout<<"调用Base1析构器"<<endl;
}
};

class Base2{
public:
Base2(int m)
{
cout<<"调用Base2带参构造器:"<<m<<endl;
}

~Base2()
{
cout<<"调用Base2析构器"<<endl;
}

};

class Base3{
public:
Base3()
{
cout<<"调用Base3无参构造器*"<<endl;
}

~Base3()
{
cout<<"调用Base3析构器"<<endl;
}
};

class Derived:public Base2,public Base1,public Base3{ //次序很重要
public:
Derived(int a,int b,int c,int d):Base1(a),member2(d),member1(c),Base2(b)
{
}
//主要基类名的个数与顺序,主要成员对象名的个数与顺序

private:
Base1 member1;
Base2 member2;
Base3 member3;
};

int main()
{
Derived obj(1,2,3,4);
return 0;
}


(一).运行结果



(二).结果分析

结果分析分为3块

1.第一块—结果前三行

首先调用基类构造器,又根据继承下来的顺序(Base2->Base1->Base3),所以出现前三行的结果顺序

2.第二块—结果4-6行,执行完基类构造器后,执行子类的新增数据成员(member)

3.第三块—7-12行,因为子类构造器函数体内没有需要执行的语句,那就接下去执行析构器,重点来了,析构器的执行顺序是怎么样的?

析构器与构造器调用顺序相反,那么如何相反呢?

代码结果中可以很清楚看出,从子类析构相反到基类析构相反的顺序执行

(三).关于哪些代码顺序重要哪些不重要总结

这里可能很多同学会搞晕,敲代码时哪些顺序要注意,哪些又不需要注意呢?

::在子类继承基类时候继承顺序是重要的,它决定子类初始化时候执行基类构造器的顺序

::子类构造器初始化列表的顺序对执行顺序没有影响,但要注意参数给构造器初始化的对应关系
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: