首页 > 编程语言 >C++中基类和派生类的析构函数

C++中基类和派生类的析构函数

时间:2023-09-01 22:34:15浏览次数:40  
标签:BaseA 函数 int C++ 析构 派生类 构造函数

和构造函数类似,析构函数也不能被继承。与构造函数不同的是,在派生类的析构函数中不用显式地调用基类的析构函数,因为每个类只有一个析构函数,编译器知道如何选择,无需程序员干涉。

C++中基类和派生类的析构函数_构造函数

另外析构函数的执行顺序和构造函数的执行顺序也刚好相反:

  • 创建派生类对象时,构造函数的执行顺序和继承顺序相同,即先执行基类构造函数,再执行派生类构造函数。
  • 而销毁派生类对象时,析构函数的执行顺序和继承顺序相反,即先执行派生类析构函数,再执行基类析构函数。

具体看实例:

#include <iostream>
    using namespace std;
    class A{
    public:
        A(){cout<<"A constructor"<<endl;}
        ~A(){cout<<"A destructor"<<endl;}
    };
    class B: public A{
    public:
        B(){cout<<"B constructor"<<endl;}
        ~B(){cout<<"B destructor"<<endl;}
    };
    class C: public B{
    public:
        C(){cout<<"C constructor"<<endl;}
        ~C(){cout<<"C destructor"<<endl;}
    };
    int main(){
        C test;
        return 0;
    }

运行结果:

C++中基类和派生类的析构函数_执行顺序_02

A constructor

B constructor

C constructor

C destructor

B destructor

A destructor

下面是一个多继承的实例:

#include <iostream>
    using namespace std;
    //基类
    class BaseA{
    public:
        BaseA(int a, int b);
        ~BaseA();
    protected:
        int m_a;
        int m_b;
    };
    BaseA::BaseA(int a, int b): m_a(a), m_b(b){
        cout<<"BaseA constructor"<<endl;
    }
    BaseA::~BaseA(){
        cout<<"BaseA destructor"<<endl;
    }
    //基类
    class BaseB{
    public:
        BaseB(int c, int d);
        ~BaseB();
    protected:
        int m_c;
        int m_d;
    };
    BaseB::BaseB(int c, int d): m_c(c), m_d(d){
        cout<<"BaseB constructor"<<endl;
    }
    BaseB::~BaseB(){
        cout<<"BaseB destructor"<<endl;
    }
    //派生类
    class Derived: public BaseA, public BaseB{
    public:
        Derived(int a, int b, int c, int d, int e);
        ~Derived();
    public:
        void show();
    private:
        int m_e;
    };
    Derived::Derived(int a, int b, int c, int d, int e): BaseA(a, b), BaseB(c, d), m_e(e){
        cout<<"Derived constructor"<<endl;
    }
    Derived::~Derived(){
        cout<<"Derived destructor"<<endl;
    }
    void Derived::show(){
        cout<<m_a<<", "<<m_b<<", "<<m_c<<", "<<m_d<<", "<<m_e<<endl;
    }
    int main(){
        Derived obj(1, 2, 3, 4, 5);
        obj.show();
        return 0;
    }

运行结果:

C++中基类和派生类的析构函数_析构函数_03

BaseA constructor

BaseB constructor

Derived constructor

1, 2, 3, 4, 5

Derived destructor

BaseB destructorBase

A destructor

从运行结果中还可以发现,多继承形式下析构函数的执行顺序和构造函数的执行顺序相反。

标签:BaseA,函数,int,C++,析构,派生类,构造函数
From: https://blog.51cto.com/u_15641375/7326818

相关文章

  • C++一阶--通讯录管理系统
    照着黑马程序员C++视频敲的,可以快速回忆起当时上课学的东西。其实当时期末的那个设计我也是敲得这个”通讯录管理系统“,这算是我大学以及编程的第一个成就。再次完成亦有感慨。先说我我想说的:体会了结构体增删改查的实现冒泡排序指针中”&“与”*“的区别函数封装的妙处......
  • C++智能指针
    一、常规指针的缺点当一个常规指针离开了作用域时,只有该指针变量本身占用的内存空间(4/8字节)会被释放,而它指向的内存空间不会自动释放,当free\delete\delete[]语句忘记执行或者无法执行,形成内存泄漏二、智能指针的优点智能指针是一个封装了常规指针的类类型对象,并且重载了......
  • C++异常处理
    一、异常处理程序的错误大致分三种:语法错误、逻辑错误、运行时错误运行时错误发生在程序运行期间发生的问题:除零、内存分配失败、非法访问内存、文件不存在、数组越界C++的异常处理机制就是为了解决运行时错误C语言中运行时错误如果不管,系统会执行默认操作,可能会让程......
  • C++模板
    一、类型信息运算符typeid在C++中typeid可以获取数据的类型,但是需要加头文件typeinfofind/usr/include-nametypeinfotypeid是运算符,执行运算符函数,执行的返回类型是type_info类类型对象type_info中有个name的成员函数type_info中还重载了==运算符,可以直接比较......
  • 标准C++ -- day09
    一、智能指针常规指针的缺点:当一个常规指针离开了作用域时,只有该指针变量本身占用的内存空间(4/8字节)会被释放,而它指向的内存空间不会自动释放,当free、delete、delete[]语句忘记执行或者无法执行,形成内存泄漏如何定位内存泄漏、如何预防内存泄漏智能指针的优点:......
  • 探索C++非质变算法:如何更高效地处理数据
    前言......
  • c++IO流——开工啦
    ......
  • c++并发编程实战-第2章 线程管控-读书笔记
    线程的基本管控每个应用程序都至少拥有一个线程,即运行main函数的线程,称为主线程,它由c++运行时系统启动。我们可以在软件运行中产生其他线程,它们以指定的函数作为入口函数。当main函数返回后,程序会退出;同样,当入口函数返回后,与之对应的线程结束。发起线程线程是通过构造std::thre......
  • 用C++如何进行判断
       ......
  • 如何进行C++动态转换
       ......