Closed ChineseBoyLY closed 4 years ago
派生类会先调用基类构造函数的。既然调用了基类的构造函数,当然要析构。 某些情况下,我们通过基类指针指向派生类,这个时候, 析构函数如果不是虚函数,并且通过基类的指针来销毁对象,那么delete 的时候就只会调用基类的构造函数。这就出问题了。
delete ptr;
只析构 ptr 指向的一个对象,但这一个对象的析构可能会有很多清理工作要做。如果发生了多态,又没有用 virtual 来修饰 ~Base(),那是不是意味着必然就会发生泄漏了。这种code的写法就是错误的?还是有其他办法来释放Base产生的内存呢?
Q:如果发生了多态,又没有用 virtual 来修饰 ~Base(),那是不是意味着必然就会发生泄漏了。这种code的写法就是错误的?
A:不一定,如果没申请堆内存、系统资源等,就不需要释放了,也就可以不需要虚析构
Q:还是有其他办法来释放Base产生的内存呢?
A:一般 Base 的析构都会自动调用的
关于多态可以看下:https://www.runoob.com/cplusplus/cpp-polymorphism.html
关于虚析构可以跑下下面的代码:
#include <iostream>
class Base
{
public:
Base() { std::cout << "Base::Base()" << std::endl; }
virtual ~Base() { std::cout << "Base::~Base()" << std::endl; }
virtual void DoSomething() { std::cout << "Base::DoSomething()" << std::endl; };
};
class Derived : public Base
{
public:
Derived() { std::cout << "Derived::Derived()" << std::endl; };
~Derived() { std::cout << "Derived::~Derived()" << std::endl; };
void DoSomething() { std::cout << "Derived::DoSomething()" << std::endl; };
};
int main()
{
Base *p = new Derived;
p->DoSomething();
delete p;
return 0;
}
然后删掉基类析构的 virtual
,再跑下,看看调用的方法与顺序就清楚了。
@ChineseBoyLY 如果没有其他问题,我将关闭这个 issue
// 因为Base有虚析构函数(virtual ~Base() {}),所以 delete 时,会先调用派生类(Derived)析构函数,再调用基类(Base)析构函数,防止内存泄漏。 delete ptr; ptr = nullptr;
对于这里不是很理解。意思是实际调用的是delete ptr; 内部却自动析构了2个对象?