例如,我有两个"接口"和类类型:
class IPlugin
{
public:
virtual void Load(void) = 0;
virtual void Free(void) = 0;
};
class IFoo
{
public:
virtual void Foo(void) = 0;
};
class Tester: public IPlugin, public IFoo
{
public:
Tester() {};
~Tester() {};
virtual void Load()
{
// Some code here
}
virtual void Free()
{
// Some code here
}
virtual void Foo(void)
{
// Some code here
}
};
Run Code Online (Sandbox Code Playgroud)
vtab实际上具有哪种结构类型Tester?而如何将 dynamic_cast运营商的行为(我的意思是如何dynamic_cast操作员将扫描vtab为有效的引用类型皈依)的表达式:
Tester* t = new Tester();
IPlugin* plg = dynamic_cast<IPlugin*>(t);
IFoo* f = dynamic_cast<IFoo*>(plg);
Run Code Online (Sandbox Code Playgroud)
提前致谢!
Mar*_*age 18
C++中的虚拟表是一个实现细节.一种可能的实现方式如下图所示.

存在类(A和B)的两个实例.每个实例都有两个vtbl指针,vtbl包含指向实际代码的指针.
在您的示例中没有实例数据,但为了说明的目的,我假设每个类包含一些实例数据.
如图所示,当指向指向Tester指针IFoo的指针被调整时.它不是指向实例数据的开头,而是指向实例数据的IFoo一部分.
巧妙的是,使用IFoo指针的调用者IFoo对该类部分周围的数据没有任何了解.对于使用IPlugin指针的调用者来说也是如此.该指针恰好指向指针指向的实例数据的开始,Tester但只有使用Tester指针的调用者才知道实例数据的整个布局.
使用dynamic_cast需要图中没有的RTTI(运行时类型信息).vtbl将包含额外的类型信息,这些信息给出了一个IFoo指向实例的指针,Tester允许代码在运行时发现指针指向的实际对象类型并使用它来向下转换指针.
vtab实际上具有什么结构,例如Tester类型?
虚拟调度的机制是实现定义的.C++标准不要求vtable和vptr,并且程序员用C++编程甚至不需要知识,因为你无法访问虚拟表(即使你的编译器实现了这个); 它由编译器生成并添加到您的代码中,就像它在将代码转换为机器代码之前为代码做了很多事情.
Tester* t = new Tester();
IPlugin* plg = dynamic_cast<IPlugin*>(t);
IFoo* f = dynamic_cast<IFoo*>(plg);
Run Code Online (Sandbox Code Playgroud)
dynamic_cast第二行不需要这里.以下就足够了:
Tester* t = new Tester();
IPlugin* plg = t; //upcast - dynamic_cast not needed
IFoo* f=dynamic_cast<IFoo*>(plg); //horizontal-cast - dynamic_cast needed
Run Code Online (Sandbox Code Playgroud)
dynamic_cast在upcast中不需要; 它只需要向下投射和水平投射.
Tester* tester1 = dynamic_cast<Tester*>(plg); //downcast - dynamic_cast needed
Tester* tester2 = dynamic_cast<Tester*>(f); //downcast - dynamic_cast needed
Run Code Online (Sandbox Code Playgroud)
在ISO/IEC 14882第二版2003-10-15中,不存在像vptr,虚拟表这样的术语,因此它完全取决于编译器实现者.
有关impl的信息.在microsoft的visual C++中:http: //www.openrce.org/articles/files/jangrayhood.pdf
关于impl的文章.g ++中的虚拟表:http: //phpcompiler.org/articles/virtualinheritance.html