如果我们没有虚拟构造函数那么为什么我们有虚拟析构函数?构造函数也可以是虚拟的吗?
答案 0 :(得分:21)
A* a = new B;
个继承
来自B
],后来你A
- 编译器无法做到
知道delete a;
是a
[在一般情况下],并会调用B
' s
析构函数 - 如果它不是虚拟的,你可能会遇到内存泄漏,
或其他错误。A
的析构函数是
调用,因为B
对象被销毁。答案 1 :(得分:2)
需要虚拟析构函数,因为在销毁时,您并不总是知道您正在处理的类型:
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;
}
上述程序delete
中的main
无法知道其p
是指向Base
还是Derived
对象,但{ {1}}析构函数为Base
(应该如此),然后virtual
可以使用delete
的{{3}}来查找正确的析构函数。
相比之下,在施工时,你总是知道你正在创造什么样的物体。 (如果你没有,那么你可以创建一个工厂或者知道的“vtable”。)
答案 2 :(得分:0)
#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)将调用基类的析构函数但实际的座右铭是删除派生类。因此我们需要析构函数本质上是虚拟的。