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

4

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


可能是为什么C++没有虚构造函数?的重复问题。 - Tomasz Nurkiewicz
1
@TomaszNurkiewicz:我认为问题更多的是,为什么C++中有虚析构函数? - Fred Foo
3个回答

27
  • 虚构造函数没有意义-您声明确切地创建了什么类型,而且在编译时已经知道。编译器不需要(实际上也不能,因为动态调度是基于对象创建之后才创建的信息)。因此不存在虚构造函数
  • 虚析构函数非常重要,可以防止内存泄漏和监控系统。假设您有A* a = new B;[BA继承], 并且稍后delete a; - 编译器无法知道aB[在一般情况下],并将调用A的析构函数-如果它不是虚拟的,则可能会导致内存泄漏或其他故障。
  • 使用虚析构函数-您确保调用B的析构函数,因为正在销毁B对象

2
我不理解第一点,请您能详细说明一下吗? - devsda
2
@jhamb:当您调用构造函数时,就像new MyClass;一样。创建的对象的动态类型静态类型完全相同,是真正的具体对象。 - amit

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;
}

在上述程序中,main 中的 delete 不知道它的指针 p 指向的是一个 Base 对象还是一个 Derived 对象,但如果 Base 析构函数是虚拟的(应该是这样),那么 delete 可以使用 *p虚函数表 找到正确的析构函数。
相比之下,在构建对象时,您始终知道正在创建的对象类型。 (如果不知道,则可以创建一个工厂或 “虚构造函数” 来解决。)

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)将调用基类的析构函数,而实际上我们的目的是删除派生类。因此,我们需要将析构函数设置为虚拟的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接