了解虚拟析构函数

苏咸

我试图使自己熟悉OOP概念,但不能完全理解OOP的概念virtual

  1. 可以创建一个,virtual destructor但不能创建一个virtual constructor为什么?
  2. virtual destructors内部如何处理?我的意思是虚拟析构函数链接说明了这一概念,但我的问题是如何vptr同时vtable调用s(派生基数和基数)的?(在虚拟成员函数的情况下,通常发生这种情况时vptr,将仅调用派生类所指向的函数
  3. 还有其他可能需要使用的方案virtual destructor吗?

任何人都可以通过链接/示例来帮助我理解以上概念吗?

巴拉克的手

首先,介绍一下虚拟功能和非虚拟功能之间的区别:

在编译或链接期间,可以解析代码中的每个非虚拟函数调用。

通过resolve,我们的意思是函数的地址可以由编译器或链接器计算。

因此,在创建的目标代码中,可以使用操作码替换函数调用,以跳转到内存中该函数的地址。

使用虚函数,您可以调用只能在运行时解析的函数。

我们不做解释,而是通过一个简单的场景进行说明:

class Animal
{
    virtual void Eat(int amount) = 0;
};

class Lion : public Animal
{
    virtual void Eat(int amount) { ... }
};

class Tiger : public Animal
{
    virtual void Eat(int amount) { ... }
};

class Tigon : public Animal
{
    virtual void Eat(int amount) { ... }
};

class Liger : public Animal
{
    virtual void Eat(int amount) { ... }
};

void Safari(Animal* animals[], int numOfAnimals, int amount)
{
    for (int i=0; i<numOfAnimals; i++)
        animals[i]->Eat(amount);
    // A different function may execute at each iteration
}

如您可能理解的那样,该Safari功能使您可以灵活地饲养不同的动物。

但是,由于直到运行时才知道每种动物的确切类型,因此Eat要调用的确切函数也是如此


类的构造函数不能是虚拟的,因为:

通过对象类的V表执行对象的虚函数的调用。

每个对象都拥有一个指向其类的V表的指针,但是该指针仅在创建对象时在运行时初始化。

换句话说,仅在调用构造函数时才初始化此指针,因此构造函数本身不能是虚拟的。

除此之外,构造函数首先是虚拟的是没有意义的。

虚拟函数背后的想法是,您可以在不知道调用它们的对象的确切类型的情况下调用它们。

在创建对象时(即,当您隐式调用构造函数时),您确切地知道要创建的对象类型,因此不需要此机制。


基类的析构函数必须是虚拟的,因为:

当静态分配其类从基类继承的对象时,则在函数(如果该对象是本地的)或程序(如果该对象是全局的)的末尾,将自动调用该类的析构函数,并且依次调用基类的析构函数。

在这种情况下,析构函数是虚拟的这一事实没有任何意义。

另一方面,当您动态分配(new)一个其类从基类继承的对象时,则需要delete在程序执行的某个稍后时刻对其进行动态释放()。

delete操作者需要一个指针的对象,其中指针的类型可以是基类本身。

在这种情况下,如果析构函数是虚拟的,则delete运算符将调用该类的析构函数,而后者又将调用基类的析构函数。

但是,如果析构函数不是虚拟的,则delete运算符将调用基类的析构函数,而实际类的析构函数将永远不会被调用。

考虑以下示例:

class A
{
    A() {...}
    ~A() {...}
};

class B: public A
{
    B() {...}
    ~B() {...}
};

void func()
{
    A* b = new B(); // must invoke the destructor of class 'B' at some later point
    ...
    delete b; // the destructor of class 'B' is never invoked
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章