如果没有虚拟构造函数,那么为什么我们有虚拟析构函数?构造函数也可以是虚拟的吗?
如果没有虚拟构造函数,那么为什么我们有虚拟析构函数?构造函数也可以是虚拟的吗?
A* a = new B;
[B
从A
继承], 并且稍后delete a;
- 编译器无法知道a
是B
[在一般情况下],并将调用A
的析构函数-如果它不是虚拟的,则可能会导致内存泄漏或其他故障。B
的析构函数,因为正在销毁B
对象。new MyClass;
一样。创建的对象的动态类型和静态类型完全相同,是真正的具体对象。 - amit需要虚析构函数是因为在销毁时,你并不总是知道你正在处理的类型:
Base *make_me_an_object()
{
if (the_moon_is_full())
return new Derived();
else
return new Base();
}
int main()
{
Base *p = make_me_an_object();
delete p;
}
main
中的 delete
不知道它的指针 p
指向的是一个 Base
对象还是一个 Derived
对象,但如果 Base
析构函数是虚拟的(应该是这样),那么 delete
可以使用 *p
的 虚函数表 找到正确的析构函数。#include<iostream>
using namespace std;
class base {
protected:
int a;
};
class derived : public base {
};
int main() {
base * pointer_of_base = new derived;
delete pointer_of_base; // this will delete the base calss not the derived
}
构造函数在创建类对象时只被调用一次,因此当我们继承基类时,构造函数只会被调用一次,所以不需要是虚拟的。
但是当我们从基类指针访问派生类时,如果我们想要删除派生类的对象,我们通过基类指针来删除它,但是delete(pointer_of_base)将调用基类的析构函数,而实际上我们的目的是删除派生类。因此,我们需要将析构函数设置为虚拟的。