首先,我理解为什么virtual
在单继承和通过基指针删除对象方面需要析构函数。这特别是关于多重继承及其背后的原因。这个问题出现在我的一门大学课程中,没有人(包括教授)知道为什么会这样:
#include <iostream>
struct A
{
virtual ~A()
{
std::cout << "~A" << std::endl;
}
int memberA;
};
struct B
{
virtual ~B()
{
std::cout << "~B" << std::endl;
}
int memberB;
};
struct AB : public A, public B
{
virtual ~AB()
{
std::cout << "~AB" << std::endl;
}
};
int main()
{
AB* ab1 = new AB();
AB* ab2 = new AB();
A* a = ab1;
B* b = ab2;
delete a;
delete b;
}
输出是:
~AB
~B
~A
~AB
~B
~A
编译器如何知道在删除or时如何调用A
's 和' 的析构函数?具体来说,内存是如何布局的(特别是它的虚函数表),以便可以调用析构函数和析构函数?B
a
b
AB
A
B
我的教授建议内存将按如下方式排列(某种东西):
AB
+---------+ +----+
| A VFT | - - - - - -> | ~A |
+---------+ +----+
| memberA |
+---------+ +----+
| B VFT | - - - - - -> | ~B |
+---------+ +----+
| memberB |
+---------+
// I have no idea where ~AB would go...
我们都很好奇这些析构函数实际上是如何在内存中布局的,以及调用delete
其中一个a
或如何b
导致所有析构函数被正确调用。删除基础对象在单继承中工作是有道理的(因为有一个单独的虚函数表可以使用),但显然我没有正确理解事物,因为我无法理解单继承版本并应用它到这个多重继承示例。
那么这是如何工作的呢?