继承中的构造析构函数调用顺序

子类构造函数必须堆继承的成员进行初始化:

  1. 通过初始化列表或则赋值的方式进行初始化(子类无法访问父类私有成员)

  2. 调用父类构造函数进行初始化

    2.1  隐式调用:子类在被创建时自动调用父类构造函数(只能调用父类的无参构造函数和使用默认参数的构造函数)

    2.2  显示调用:在初始化列表调用父类构造函数(适用所有的父类构造函数)

#include <iostream>
#include <string>

using namespace std;

class PParent                //父父类
{
public:
    PParent(string s)
    {
        cout << "PParent" << s << endl;
    }
    ~PParent()
    {
        cout << "~PParent" << s << endl;
    }
};

class Parent : public PParent  // 父类
{
public:
    Parent() : PParent("Default")
    {
        cout << "Parent" << endl;
    }
    Parent(string s) : PParent(s)
    {
        cout << "Parent" << s << endl;
    }
    ~Parent()
    {
        cout << "~Parent" << endl;
    }
};

class sib_child              // 同级类
{
public:
    sib_child()
    {
        cout << "sib_child" << endl;
    }
    sib_child(string s)
    {
        cout << "sib_child" << s << endl;
    }
    ~sib_child()
    {
        cout << "~sib_child" << endl;
    }
};

class Child : public Parent    // 自己
{
    PParent pp;
    sib_child sc;
public:
    Child() : pp("Default 1")
    {
        cout << "Child" << endl;
    }
    Child(string s) : Parent(s), sc(s) // 先调用父类构造函数,再调用同类构造函数
    {
        cout << "Child" << s << endl;
    }
    ~Child()
    {
        cout << "~Child" << endl;
    }
};

int main()
{
    Child cc("call");
    // 构造顺序
    // PParent   : call         父父类
    // Parent    : call          父类
    // sib_child : call         同类
    // Child     : call            自己

    return 0;
    // 析构顺序
    // ~Child     : call            自己
    // ~sib_child : call         同类
    // ~Parent    : call          父类
    // ~PParent   : call         父父类
}

构造函数调用顺序:

  1. 执行父类构造函数

  2. 执行同级构造函数

  3. 执行自己构造函数

析构函数调用顺序:

  1. 执行自己析构函数

  2. 执行同级析构函数

  3. 执行父类析构函数

原文地址:https://www.cnblogs.com/zsy12138/p/10846437.html

时间: 2024-10-13 02:12:40

继承中的构造析构函数调用顺序的相关文章

C++类的继承中构造函数和析构函数调用顺序例子

/*当建立一个对象时,首先调用基类的构造函数,然后调用下一个派生类的构造函数,依次类推,直至到达派生类次数最多的派生次数最多的类的构造函数为止.简而言之,对象是由“底层向上”开始构造的.因为,构造函数一开始构造时,总是要调用它的基类的构造函数,然后才开始执行其构造函数体,调用直接基类构造函数时,如果无专门说明,就调用直接基类的默认构造函数.在对象析构时,其顺序正好相反.下面的这个程序说明这个问题*///-----------------------------------------------

C++多重继承中构造函数和析构函数调用顺序举例

//多重继承 #include <iostream> using namespace std; class A { public:     A()     {         cout<<"A基类构造A::A()"<<endl;     }     ~A()     {         cout<<"A基类析构A::~A()"<<endl;     } }; class B:public A { publi

C++ 类的继承三(继承中的构造与析构)

//继承中的构造与析构 #include<iostream> using namespace std; /* 继承中的构造析构调用原则 1.子类对象在创建时会首先调用父类的构造函数 2.父类构造函数执行结束后,执行子类的构造函数 3.当父类的构造函数有参数时,需要在子类的初始化列表中显示调用 4.析构函数调用的先后顺序与构造函数相反 继承与其他类做成员变量混搭的情况下,构造和析构嗲用原则 1.先构造父类,在构造成员变量,最后构造自己 2.先析构自己,再析构成员变量,最后析构父类 */ clas

C++--第16课 - 继承中的构造与析构

第16课 - 继承中的构造与析构 1. 赋值兼容性原则 (1)      子类对象可以当作父类对象使用. (2)      子类对象可以直接赋值给父类对象. (3)      子类对象可以直接初始化父类对象. (4)      父类指针可以直接指向子类对象. (5)      父类引用可以直接引用子类对象. 子类就是特殊的父类 #include <cstdlib> #include <iostream> using namespace std; class Parent { pro

C++--继承中的构造与析构、父子间的冲突

一.继承中的构造与析构 Q:如何初始化父类成员?父类构造函数与子类构造函数由什么关系?A.子类对象的构造1.子类在可以定义构造函数2.子类构造函数--必须对继承而来的成员进程初始化(直接通过初始化列表或者赋值的方式进行初始化,调用父类构造函数进行初始化)B.父类构造函数在子类中的调用方式1.默认调用--适用于无参构造函数和使用默认参数的构造函数2.显示调用--通过初始化列表进行调用,适用于所有父类构造函数代码示例 #include <iostream> #include <string&

c++深/浅拷贝 &amp;&amp; 构造函数析构函数调用顺序练习题

1.深/浅拷贝 编译器为我们提供的合成拷贝构造函数以及合成的拷贝赋值运算符都是浅拷贝.浅拷贝只是做简单的复制,如果在类的构造函数中new出了内存,浅拷贝只会简单的复制一份指向该内存的指针,而不会再开辟内存,这就会使得程序运行出现内存错误,如此,当对象析构的时候,会delete多次同一块内存区域,发生错误.这也就是为什么,必要的时候需要我们自己编写拷贝构造函数和重载赋值运算符,让它变成深拷贝,深拷贝即在copy指针的时候不是简单做值copy,而是还要开辟内存. 2.构造函数析构函数调用顺序练习题

C++继承中析构函数 构造函数的调用顺序以及虚析构函数

首先说说构造函数.大家都知道构造函数里就能够调用成员变量,而继承中子类是把基类的成员变成自己的成员,那么也就是说子类在构造函数里就能够调用基类的成员了,这就说明创建子类的时候必须先调用基类的构造函数,仅仅有这样子类才干在构造函数里使用基类的成员,所以是创建子类时先调用基类的构造函数然后再调用自己的构造函数.通俗点说,你要用某些物品.但这些物品你没办法自己生产,自然就要等别人生产出来,你才干拿来用. 接着就是析构函数了,上面说到子类是将基类的成员变成自己的成员,那么基类就会仅仅存在子类中直到子类调

Swift难点-继承中的构造规则实例具体解释

关于继承中的构造规则是一个难点. 假设有问题,请留言问我. 我的Swift新手教程专栏 http://blog.csdn.net/column/details/swfitexperience.html 为什么要有构造器:为类中自身和继承来的存储属性赋初值. 一.两种构造器-指定构造器和便利构造器 指定构造器:类中必备的构造器.为全部的属性赋初值.(有些子类可能不须要显示声明,由于默认从基类继承了) 便利构造器:类中的辅助构造器,通过调用指定构造器为属性赋初值.(仅在必要的时候声明) 举例 cla

【C++第十课】---继承中的构造与析构

一.继承中的赋值兼容性原则 1.子类对象可以当作父类对象使用 2.子类对象可以直接赋值给父类对象 3.子类对象可以直接初始化父类对象 4.父类指针可以直接指向子类对象 5.父类引用可以直接引用子类对象 6.子类是就是特殊的父类. 举例说明: #include <iostream> using namespace std; class Parent { protected: const char* name; public: Parent() { name= "Parent ...&q