C++中为什么要将析构函数定义成虚函数

构造函数不可以是虚函数的,这个很显然,毕竟虚函数都对应一个虚函数表,虚函数表是存在对象内存空间的,如果构造函数是虚的,就需要一个虚函数表来调用,但是类还没实例化没有内存空间就没有虚函数表,这根本就是个死循环。

可是析构函数却要定义成虚函数,这是为什么呢,写一个非常简单的例子来理解一下:

class AA {
public:
    AA() {};
    ~AA() { fun2(); };
    virtual void fun1() {
        cout << "Base construct" << endl;
    }
    virtual void fun2() {
        cout << "Base destruct" << endl;
    }
};

class BB : public AA {
public:
    BB() { fun1(); };
    ~BB() { fun2(); };
    void fun1() {
        cout << "Derive construct" << endl;
    }
    void fun2() {
        cout << "Derive destruct" << endl;
    }
};

int main()
{
    for (int i = 0; i < 1; i++) {
        //AA a;
        BB b;
    }
        return 0;
}

输出结果:

所以可以看出,派生类对象构造的时候先调用基类的构造函数再调用派生类的构造函数,析构的时候先调用派生类析构函数再调用基类析构函数。

其实这个很好理解,派生类的成员由两部分组成,一部分是从基类那里继承而来,一部分是自己定义的。那么在实例化对象的时候,首先利用基类构造函数去初始化从基类继承而来的成员,再用派生类构造函数初始化自己定义的部分。

同时,不止构造函数派生类只负责自己的那部分,析构函数也是,所以派生类的析构函数会只析构自己的那部分,这时候如果基类的析构函数不是虚函数,则不能调用基类的析构函数析构从基类继承来的那部分成员,所以就会出现只删一半的现象,造成内存泄漏。

所以析构函数要定义成虚函数。

时间: 2024-10-27 07:56:14

C++中为什么要将析构函数定义成虚函数的相关文章

析构函数定义为虚函数原因

析构函数定义为虚函数原因 先看下面一段程序: #include <iostream> using namespace std; class Person { public: virtual ~Person()                    //加了virtual,讲析构函数声明为虚函数 {    cout << "Person::~Person()" << endl; } }; class Student : public Person {

为什么有时候需要把析构函数定义为虚函数

为什么有时候需要把析构函数定义为虚函数 析构函数的作用是在对象撤销之前做必要的清理现场的工作,当派生类的对象从内存中撤销时一般先调用派生类的析构函数,然后在调用基类的析构函数,但是用new运算符建立了一个派生类对象,并且把他赋给基类指针,那么当用delete运算符撤销这个指针指向的存储空间的时候,系统会只执行基类的析构函数,而不执行派生类的析构函数.

从为什么要将基类的析构函数定义为虚函数谈起~~

 首先,做一个最简单的实验,在电脑上运行下面的代码,将会产生运行错误,这或许会使你百思不得其解: #include <iostream> using namespace std; class Base { private: int a; public: ~Base(){cout << "Base dtor..." << endl;} }; class Derived : public Base { private: int b; public: ~D

什么时候需要将析构函数定义为虚函数,如果不这么做,会存在什么问题?

这是网易游戏面我的一道题,当时想了一想,结果答错了,没在意,今天测试了一下,结果才认识到问题所在! 直接看代码: class Interface { public: virtual void fun() = 0; Interface() { cout<<"Interface::Interface()"<<endl; _data = new char[10]; } virtual ~Interface() { cout<<"Interface

析构函数定义为虚函数

析构函数执行时先调用派生类的析构函数,其次才调用基类的析构函数.如果析构函数不是虚函数,而程序执行时又要通过基类的指针去销毁派生类的动态对象,那么用delete销毁对象时,只调用了基类的析构函数,未调用派生类的析构函数.这样会造成销毁对象不完全. #include<iostream.h> #include<stdlib.h> class CPerson { public: virtual ~CPerson(); //基类的析构函数必须声明为虚函数,否则 用delete销毁对象时会出

C++ Primer 学习笔记33_面向对象编程(4)--虚函数与多态(一):多态、派生类重定义、虚函数的访问、 . 和-&gt;的区别、虚析构函数、object slicing与虚函数

C++ Primer学习笔记33_面向对象编程(4)--虚函数与多态(一):多态.派生类重定义.虚函数的访问. . 和->的区别.虚析构函数.object slicing与虚函数 一.多态 多态可以简单地概括为"一个接口,多种方法",前面讲过的重载就是一种简单的多态,一个函数名(调用接口)对应着几个不同的函数原型(方法). 更通俗的说,多态行是指同一个操作作用于不同的对象就会产生不同的响应.或者说,多态性是指发出同样的消息被不同类型的对象接收时有可能导致完全不同的行为. 多态行分

析构函数什么情况下要定义为虚函数?

原文出处:点击我:) 1.第一段代码 #include<iostream>using namespace std;class ClxBase{public:    ClxBase() {};    ~ClxBase() {cout << "Output from the destructor of class ClxBase!" << endl;}; void DoSomething() { cout << "Do someth

为什么基类的析构函数要写成虚函数?

为什么基类的析构函数要写成虚函数? 答:在实现多态时,当用基类操作派生类,在析构时防止只析构基类而不析构派生类的状况发生. 代码说明如下 第一段代码: 1 #include<iostream> 2 using namespace std;   3    4 class ClxBase   5 {public:   6 ClxBase() {}   7 ~ClxBase() {cout << "Output from the destructor of class ClxB

虚析构函数与纯虚函数

虚析构函数 通过基类的指针删除派生类对象时,通常情况只调用基类的析构函数 但是,删除一个派生类对象时,应该先调用派生类的析构函数,然后调用基类的析构函数(构造时自顶向下,析构时自底向上) 这种情况会产生内存泄漏,最终导致系统应可用内存不足而崩溃 解决办法 把基类的析构函数声明为virtual,此时派生类的析构函数即使不声明为virtual也为virtual函数 在调用基类的指针删除派生类对象时,会先调用派生类的析构函数,最后调用基类的析构函数 一般方法 如果一个类定义了虚函数,那么析构函数也应该