我在哪里可以找到C++有状态虚拟基础的良好解释

Where can I find a good explanation of C++ stateful virtual base?

本文关键字:虚拟 解释 状态 在哪里 C++      更新时间:2023-10-16

我在哪里可以找到C++有状态虚拟基础的良好解释?

我查看了JSF C++编码标准并阅读了他们的解释,但正在寻找一些额外的信息。

感谢您提供任何其他详细信息。

Stanley Lippman的书"Inside the C++ Object Model"对这个主题进行了很好的介绍(虽然已经过时,但仍然有效)。

虚拟性是关于间接的。让我们从简单开始:

struct Foo { void bar(int, bool) {} } x;
x.bar(12, false);

在这里,对实例xFoo::bar()调用在编译时是完全已知的,并且是静态解决的:一个固定的函数,它被赋予实例引用和函数参数。函数名称、调用、完成。到目前为止没有问题。

继续前进:

struct Boo { virtual void bar(char, float) = 0; };
extern Boo * foreign_function();
Boo * p = foreign_function();
p->bar('a', -1.5);

这一次,在编译时无法知道bar()调用应该去哪里。解决此问题的唯一方法是添加一个间接级别,允许您查找此成员函数的所有可能覆盖,并在运行时根据*p的动态类型选择正确的替代。这次我们从函数名称开始,在运行时执行查找,然后进行调用。这种模式应该仍然相当熟悉。

这里的重点是,知道*p的动态类型是(非虚拟)基Boo的子类型就足够了,这样我们只需一次查找即可实现这一点(例如,指向与Boo兼容的表的 vtable 指针)。

现在谈谈大鱼:

struct Voo { virtual void doo(double, void *) = 0; };
struct Left  : virtual Voo { virtual void doo(double, void *); } };
struct Right : virtual Voo { virtual void doo(double, void *); } };
struct Most : Left, Right  { virtual void doo(double, void *); } };
Left * p = /* address of a Most object, say */;
p->doo(0.1, nullptr);

我们已经知道我们不知道doo()应该去哪里,我们必须在运行时查找它。但是,简单的一步间接寻址不再可能。尽管LeftVoo的子类,Right也是Voo的子类,但*p的实际Voo基本子对象实际上并不是Left的子对象 - 或Right子对象的子对象 - 虚拟子对象直接属于Most(或任何派生最多的对象)。在实现方面,单个 vtable 指针是不好的,因为我们不想要 Left 的 vpointer,也不想要Right的 vptr。相反,我们想要实际对象具有的任何 vpointer 。

所以现在我们发现自己处于一个熟悉的情况:我们需要查找一些我们只能在运行时知道的东西。而这一次我们需要查找的是实际的虚拟基地。所以过程是这样的:函数名称,在运行时查找虚拟基础,在虚拟基础中查找虚拟函数,然后进行调用。(在虚拟性的典型 vtable 实现中,这通常是通过"thunk"或"指向指针的指针"进行额外的查找来完成的。

简而言之,"虚拟"的意思是"在运行时确定"。

(这不会强制编译器生成运行时代码。如果在编译时可证明调度的目标已知,则可以取消虚拟化调用。但是你的程序的行为是"好像"。