没有虚拟构造函数,但虚拟析构函数

时间:2012-03-29 10:54:59

标签: oop constructor virtual-destructor

如果我们没有虚拟构造函数那么为什么我们有虚拟析构函数?构造函数也可以是虚拟的吗?

3 个答案:

答案 0 :(得分:21)

  • 虚拟构造函数中没有任何意义 - 您确切地声明了什么 类型已创建,并且在编译时是众所周知的。编译器 不需要[实际上不能,因为动态调度是基于的 关于仅在创建对象后创建的信息]。 所以没有虚拟构造函数
  • 虚拟析构函数对于防止内存泄漏非常重要 监控系统。假设您有[{1}} [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)将调用基类的析构函数但实际的座右铭是删除派生类。因此我们需要析构函数本质上是虚拟的。