多重继承的构造函数和析构函数的执行顺序(包含虚基类)

简介: C++代码:#include using namespace std;class A {public: A() { cout

C++代码

#include <iostream>
using namespace std;

class A {
public:
    A()
    {
        cout << "父类A构造函数被调用:" << endl;
    }


    virtual ~A()
    {
        cout << "父类A虚构函数被调用:" << endl;
    }
};
class B {
public:
    B()
    {
        cout << "父类B构造函数被调用:" << endl;
    }


    virtual ~B()
    {
        cout << "父类B虚构函数被调用:" << endl;
    }
};

class C : public A, virtual public B
{
public:
    C()
    {
        cout << "C子类构造函数被调用" << endl;
    }


    ~C()
    {
        cout << "C子类虚构函数被调用:" << endl;
    }
};

int main()
{
    cout << "B类是C类的虚基类,A类是C类的非虚基类" << endl;
    cout << "----------下面是执行顺序------------" << endl;
    A *pa = new C();
    delete pa;
    system("PAUSE");
    return(0);
}

运行结果:

这里写图片描述

简单分析:

多重继承的情况下,严格按照派生类定义时从左到右的顺序来调用构造函数,析构函数与之相反。但是如果基类(基类,父类,超类是指被继承的类,派生类,子类是指继承于基类的类.)中有虚基类的话则构造函数的调用顺序如下:
(1) 虚基类的构造函数在非虚基类的构造函数之前调用;(比如在本例中B构造函数是虚基类所以在A构造函数之前执行)
(2) 若同一层次中包含多个虚基类,这些虚基类的构造函数按照他们的说明顺序调用;
(3) 若虚基类由非虚基类派生而来,则任然先调用基类构造函数,再调用派生诶,在调用派生类的构造函数。

目录
相关文章
|
存储 Cloud Native Linux
C++ 继承下的构造函数和析构函数执行顺序
C++ 继承下的构造函数和析构函数执行顺序
|
5月前
|
Java 编译器 程序员
C++中的语法知识虚继承和虚基类
**C++中的多继承可能导致命名冲突和数据冗余,尤其在菱形继承中。为解决这一问题,C++引入了虚继承(virtual inheritance),确保派生类只保留虚基类的一份实例,消除二义性。虚继承通过`virtual`关键字指定,允许明确访问特定路径上的成员,如`B::m_a`或`C::m_a`。这样,即使基类在继承链中多次出现,也只有一份成员副本,简化了内存布局并避免冲突。虚继承应在需要时提前在继承声明中指定,影响到从虚基类派生的所有后代类。**
|
编译器 C++
44 C++ - 继承中的构造和析构
44 C++ - 继承中的构造和析构
51 0
|
7月前
|
编译器 C语言 C++
C++类和对象的细节原理:this指针、构造函数和析构函数、深浅拷贝、运算符重载、初始化列表、类的各种成员和方法
C++类和对象的细节原理:this指针、构造函数和析构函数、深浅拷贝、运算符重载、初始化列表、类的各种成员和方法
73 0
|
存储 编译器 C语言
【C++学习】类和对象 | 类的成员函数存放在哪里?| this指针 | 构造函数 | 析构函数 | 探索构造和析构函数的更多细节
【C++学习】类和对象 | 类的成员函数存放在哪里?| this指针 | 构造函数 | 析构函数 | 探索构造和析构函数的更多细节
211 0
|
存储 C++ 开发者
你还不进来看看C++类与对象【7】 —— 动态多态底层原理剖析&&(纯)虚析构解决父类指针不能释放子类属性问题嘛
你还不进来看看C++类与对象【7】 —— 动态多态底层原理剖析&&(纯)虚析构解决父类指针不能释放子类属性问题嘛
140 0
你还不进来看看C++类与对象【7】 —— 动态多态底层原理剖析&&(纯)虚析构解决父类指针不能释放子类属性问题嘛
|
存储 编译器 C++
【C++要笑着学】虚函数表(VBTL) | 观察虚表指针 | 运行时决议与编译时决议 | 动态绑定与静态绑定 | 静态多态与动态多态 | 单继承与多继承关系的虚表(二)
虚表是编译器的实现,而非C++的语言标准。上一章我们学习了多态的概念,本章我们深入探讨一下多态的原理。文章开头先说虚表指针,观察编译器的查表行为。首次观察我们先从监视窗口观察美化后的虚表 _vfptr,再透过内存窗口观察真实的 _vfptr。我们还会探讨为什么对象也能切片却不能实现多态的问题。对于虚表到底存在哪?我们会带着大家通过一些打印虚表的方式进行比对!铺垫完虚表的知识后,会讲解运行时决议与编译时决议,穿插动静态的知识点。文章的最后我们会探讨单继承与多继承的虚表,多继承中的虚表神奇的切片指针偏移问题,这块难度较大,后续我们会考虑专门讲解一下,顺带着把钻石虚拟继承给讲了
383 1
【C++要笑着学】虚函数表(VBTL) | 观察虚表指针 | 运行时决议与编译时决议 | 动态绑定与静态绑定 | 静态多态与动态多态 | 单继承与多继承关系的虚表(二)
|
存储 设计模式 安全
如何理解子类对象赋值给父类(深入理解动态绑定、静态绑定)
如何理解子类对象赋值给父类(深入理解动态绑定、静态绑定)
如何理解子类对象赋值给父类(深入理解动态绑定、静态绑定)
|
存储 编译器 C++
【C++要笑着学】虚函数表(VBTL) | 观察虚表指针 | 运行时决议与编译时决议 | 动态绑定与静态绑定 | 静态多态与动态多态 | 单继承与多继承关系的虚表(一)
虚表是编译器的实现,而非C++的语言标准。上一章我们学习了多态的概念,本章我们深入探讨一下多态的原理。文章开头先说虚表指针,观察编译器的查表行为。首次观察我们先从监视窗口观察美化后的虚表 _vfptr,再透过内存窗口观察真实的 _vfptr。我们还会探讨为什么对象也能切片却不能实现多态的问题。对于虚表到底存在哪?我们会带着大家通过一些打印虚表的方式进行比对!铺垫完虚表的知识后,会讲解运行时决议与编译时决议,穿插动静态的知识点。文章的最后我们会探讨单继承与多继承的虚表,多继承中的虚表神奇的切片指针偏移问题,这块难度较大,后续我们会考虑专门讲解一下,顺带着把钻石虚拟继承给讲了
655 0
【C++要笑着学】虚函数表(VBTL) | 观察虚表指针 | 运行时决议与编译时决议 | 动态绑定与静态绑定 | 静态多态与动态多态 | 单继承与多继承关系的虚表(一)
|
编译器 C++
【一、构造函数与析构函数】深度解析C++类的构造函数与析构函数调用机制
【一、构造函数与析构函数】深度解析C++类的构造函数与析构函数调用机制
575 0