这个是继承才产生的问题,比如A类是B类的父类,学生时代可能遇到可能的代码比较多的是:

A *a=new B;

是一个父类指针指向子类开辟的空间,然后delete a的时候只会delete掉指针,不会delete掉指向的空间。

void func(A *a);

这里的func函数可以接受A类 对象指针也可以接受B类对象指针然后在func里面,所以通常简便处理,我们只会写这样一个函数去处理A类对象指针以及它所有的继承类,不然如果A有100个继承类,每个类都写一样的方法,继承还有什么用?仔细看如下代码:

#include <iostream>
#include <memory>
#include <string>
#include <thread>
#include <vector>
#include <mutex>
#include <random>

class A
{
public:
    A()
    {
        std::cout << "Construct A:" << std::endl;
    }
    virtual void print() 
    {
        std::cout << "A:" << std::endl;
    }
     ~A()
    {
        std::cout << "~A:" << std::endl;
    }
};

class B:public A
{
public:
    B()
    {
        std::cout << "Construct B:" << std::endl;
    }
    void print()
    {
        std::cout << "B:" << std::endl;
    }
    ~B()
    {
        std::cout << "~B:" << std::endl;
    }
};

void func(A *a)
{
    a->print();
}

int main()
{
    A *a = new A;
    A *b = new B;
    func(a);
    func(b);
    delete a;
    delete b;
    return 0;
}

输出结果如下:
图片说明
由于A没有虚析构函数,B类构造了但是没能析构,这样的情况多了就会导致内存泄漏。
类似的工作里面还会经常用std::vector<A*>来存储所有A类以及A类继承类的指针,那么一定要把所有的父类(A类)的析构函数设为虚析构函数。