你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

C++——继承中的构造和析构

[复制链接]
gaosmile 发布时间:2020-8-21 10:03
在我们前面学习过类中的构造函数,以及析构函数,那么自然而然,在继承关系中,必然是存在着析构和构造着。
一、子类对象的构造
1、问题的引出
如何初始化父类成员?
父类构造函数和子类构造函数有什么关系?
2、子类中的构造函数怎样初始化父类成员:
  • 子类中也是可以定义构造函数的:

--必须对继承而来的成员进行初始化,那么怎样初始化呢?这里有两种方式:
-直接通过初始化列表或者赋值的方式进行初始化
-调用父类构造函数进行初始化
3、父类构造函数在子类中的调用方式
  • 默认调用

-适用于无参构造函数和使用默认参数的构造函数
  • 显示调用

-通过初始化列表进行调用
-适用于所有父类构造函数
实践代码模板:
class Child :public Parent
{
  public:
     Child()//隐式调用
     {
        cout<< "Child()" <<endl;
     }
     Child(string s)
  :Parent("Parent to Parent")
  {
     cout<<"Child()"<<s<<endl;
  }
};
代码实践:
#include <iostream>
#include <string>

using namespace std;

class Parent
{
public:
    Parent()
    {
        cout << "Parent()" << endl;
    }
    Parent(string s)
    {
        cout << "Parent(string s) : " << s << endl;
    }
};

class Child : public Parent
{
public:
    Child()
    {
        cout << "Child()" << endl;
    }
    Child(string s) : Parent(s)
    {
        cout << "Child(string s) : " << s << endl;
    }
};

int main()
{      
    Child c;
    Child cc("cc");
   
    return 0;
}

输出结果:
root@txp-virtual-machine:/home/txp# ./a.out
Parent()
Child()
Parent(string s) : cc
Child(string s) : cc

注解:通过上面的代码输出结果,我们可以发现,子类定义的对象如果没有没有传参,就隐式调用父类的构造函数;当然上面也使用了显示调用,通过初始列表的就可以看出。
4、构造规则
  • 子类对象在创建时会首先调用父类的构造函数
  • 先执行父类构造函数再执行子类的构造函数
  • 父类构造函数可以被隐式调用或者显示调用

5、对象创建时构造函数的调用顺序
  • (1)调用父类的构造函数
  • (2)调用成员变量的构造函数
  • (3)调用类自身的构造函数

总结:先父母,后客人,再自己
代码实践:
#include <iostream>
#include <string>

using namespace std;

class Object
{
public:
    Object(string s)
    {
        cout << "Object(string s) : " << s << endl;
    }
};

class Parent : public Object
{
public:
    Parent() : Object("Default")
    {
        cout << "Parent()" << endl;
    }
    Parent(string s) : Object(s)
    {
        cout << "Parent(string s) : " << s << endl;
    }
};

class Child : public Parent
{
    Object mO1;
    Object mO2;
public:
    Child() : mO1("Default 1"), mO2("Default 2")
    {
        cout << "Child()" << endl;
    }
    Child(string s) : Parent(s), mO1(s + " 1"), mO2(s + " 2")
    {
        cout << "Child(string s) : " << s << endl;
    }
};

int main()
{      
    Child cc("cc");
   
    return 0;
}

输出结果:
root@txp-virtual-machine:/home/txp# ./a.out
Object(string s) : cc
Parent(string s) : cc
Object(string s) : cc 1
Object(string s) : cc 2
Child(string s) : cc

注解:我们可以看到,先定义了一个Child对象,然后最先访问Object带参构造函数,然后再是Parent带参构造函数(说白了就是父类先触发),然后在子类Child中又包含了组合关系(也就是客人),然后Object类中的带参构造函数,最后再触发自身的带参构造函数。
二、子类对象的析构
1、析构函数的调用顺序与构造函数相反
  • (1)执行自身的析构函数
  • (2)执行成员变量的析构函数
  • (3)执行父类的析构函数

代码实践:
#include <iostream>
#include <string>

using namespace std;

class Object
{
    string ms;
public:
    Object(string s)
    {
        cout << "Object(string s) : " << s << endl;
        ms = s;
    }
    ~Object()
    {
        cout << "~Object() : " << ms << endl;
    }
};

class Parent : public Object
{
    string ms;
public:
    Parent() : Object("Default")
    {
        cout << "Parent()" << endl;
        ms = "Default";
    }
    Parent(string s) : Object(s)
    {
        cout << "Parent(string s) : " << s << endl;
        ms = s;
    }
    ~Parent()
    {
        cout << "~Parent() : " << ms << endl;
    }
};

class Child : public Parent
{
    Object mO1;
    Object mO2;
    string ms;
public:
    Child() : mO1("Default 1"), mO2("Default 2")
    {
        cout << "Child()" << endl;
        ms = "Default";
    }
    Child(string s) : Parent(s), mO1(s + " 1"), mO2(s + " 2")
    {
        cout << "Child(string s) : " << s << endl;
        ms = s;
    }
    ~Child()
    {
        cout << "~Child() " << ms << endl;
    }
};

int main()
{      
    Child cc("cc");
   
    cout << endl;
   
    return 0;
}

输出结果:
root@txp-virtual-machine:/home/txp# ./a.out
Object(string s) : cc
Parent(string s) : cc
Object(string s) : cc 1
Object(string s) : cc 2
Child(string s) : cc

~Child() cc
~Object() : cc 2
~Object() : cc 1
~Parent() : cc
~Object() : cc

三、总结:
  • 子类对象在创建时需要调用父类构造函数进行初始化
  • 先执行父类构造函数然后执行成员的构造函数
  • 父类构造函数显示调用需要在初始化列表中进行
  • 子类对象在销毁时需要调用父类析构函数进行清理
  • 析构顺序与构造顺序对称相反

好了,今天的分享就到这里,如果文章中有错误或者不理解的地方,可以交流互动,一起进步。

收藏 评论0 发布时间:2020-8-21 10:03

举报

0个回答

所属标签

STM32团队

意法半导体微控制器和微处理器拥有广泛的产品线,包含低成本的8位单片机和基于ARM® Cortex®-M0、M0+、M3、M4、M33、M7及A7内核并具备丰富外设选择的32位微控制器及微处理器


最新内容

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
微信公众号二维码 微信公众号
手机版二维码 手机版