c++中父类的析构函数为什么要是虚函数,否则会造成内存泄露

我们先来看一段简单代码,A类有一个指针成员_pa,B类公有继承了A类,然后自己有一个指针成员_pb:

class A{
public:
    A(int x = 1)
        :_pa(new int(x))
    {}

    ~A()
    {
        cout << "~A()" << endl;
    }
protected:
    int* _pa;
};

class B : public A{
public:
    B(int b)
        :A(b)
        ,_pb(new int(b))
    {}

    ~B()
    {
        cout << "~B()" << endl;
    }
protected:
    int* _pb;
};

 

如果不把父类的析构函数定义为虚函数,会有什么问题?

void Test()
{
A* pa = new B(0);//父类的指针指向了子类的对象
delete pa;//
}
pa是A类的指针,它指向了新创建的B类对象,在析构时,理应调用B类的析构函数,然后执行结果是调用了A类的析构函数:

原因就是,没有构成多态,与类型有关,因为pa是父类的指针,就一定调用的是父类的析构函数。
但如果把A类的析构函数定义为虚函数:

......
virtual ~A()
{
cout << "~A()" << endl;
}
......

问题是,父子的析构函数名字不相同,就算我加了virtual使父类的析构函数变为虚函数,也不会被子类重写啊。
其实,析构函数是一个特殊的函数,编译器在编译时,析构函数的名字统一为destucter,所以只要父类的析构函数定义为虚函数,不管子类的析构函数前是否加virtual(可以理解为编译器优化),都构成重写。
再看刚才的问题:

void Test()
{
A* pa = new B(0);//父类的指针指向了子类的对象
delete pa;//
}

父类的指针指向了子类的对象,然后调用重写虚函数——析构函数,不就构成了多态嘛,而多态与类型无关,只与对象有关,所以调用的就是子类的析构函数了。
————————————————

原文链接:https://blog.csdn.net/han8040laixin/article/details/81704165

posted @ 2021-09-15 08:24  春香  阅读(284)  评论(0编辑  收藏  举报