了解虚拟函数和析构函数调用

Understanding virtual functions and destructors calling

本文关键字:析构 函数调用 函数 虚拟 了解      更新时间:2023-10-16

我对两个代码块感到困惑。我会写下我的期望和结果。因此:

我有这样的代码:

#include <iostream>
class Base {
void method() {std::cout << "from Base" << std::endl;}
public:
virtual ~Base() {method();}
void baseMethod() 
{
method();
}
};
class A : public Base {
void method() {std::cout << "from A" << std::endl;}
public:
~A() {
std::cout<<"Destructor a" << std::endl;
method();
}
void baseMethod() 
{
std::cout<<"Called A" << std::endl;
method();
}
};
int main(void) {
Base* base = new A;
base->baseMethod();
delete base;
return 0;
}

并在终端中输出:

from Base
Destructor a
from A
from Base

问题是,method()不是虚拟的。例如,在main函数中的baseMethod()调用中,调用base->baseMethod(。由于method()不是虚拟的,它调用基类方法并打印"From Base"。还可以。

但是。。删除带线的基点时

delete Base;

由于基类析构函数是虚拟的,它调用派生类析构函数~A()。在这个析构函数中,method()调用。但是通过查看输出,这个method()调用调用类A的method(。但是method()不是虚拟的。基类指针调用的析构函数,很快,我在析构函数A中期望From B,但它打印From A。它是怎么回事。

我的期望:

from Base
Destructor a
from Base
from Base

当我将虚拟添加到此行时:

class Base {
virtual void method() {std::cout << "from Base" << std::endl;}

输出为:

from A
Destructor a
from A
from Base

您可以看到,从baseMethod调用的method()中的行为发生了变化,输出也发生了变化。但在~A()析构函数中,行为是相同的。

~A()的主体在A的词法范围内。因此,~A()中的调用method()被静态地绑定到A::method。不多不少。

由于~A()正在被调用,它反过来调用这个静态绑定的成员函数。