C++ 多态性中的虚拟表

C++ 多态性中的虚拟表,c++,polymorphism,vtable,C++,Polymorphism,Vtable,我读过很多帖子,每个人都说,虚拟表是每个类,而不是每个对象,对象只有指向共享vtable的vtpr指针。但是请考虑这个例子: class Base { public: virtual void func1(void) {} virtual void func2(void) {} private: int dummy; }; class Der1 : public Base { public: virtual void func1(void) {} private

我读过很多帖子,每个人都说,虚拟表是每个类,而不是每个对象,对象只有指向共享vtable的vtpr指针。但是请考虑这个例子:

class Base
{
public:
    virtual void func1(void) {}
    virtual void func2(void) {}
private:
    int dummy;
};

class Der1 : public Base
{
public:
    virtual void func1(void) {}
private:
    int dummy;
};

class Der2 : public Base
{
public:
    virtual void func2(void) {}
private:
    int dummy;
};

int main(void)
{
    Base * obj1 = new Der1;
    Base * obj2 = new Der2;
}
obj1和obj2是否与唯一的基类vtable相关?我相信答案是否定的,但你能解释一下吗?如果这两个对象都与同一个vtable相关,那么如何确定要调用哪些方法?例如,obj1->func1引用不同于obj2->func1

更新:

执行
Base*obj1=new Der1时执行哪些操作?有人能为这些操作编写一个伪代码吗?

我希望下面的插图能有所帮助。派生类只是复制基类的虚拟表,但它们可以修改相应的条目。红色部分表示给定类修改了v表中的条目。所以,在创建派生类的实例时,会考虑修改后的表(特定于该类)

如何处理基类的双重性取决于编译器(如果基类有大量函数-派生函数是否会有整个虚拟函数表的副本,并且是否会修改条目?)。 在我看来,编译器将简单地为每个派生类复制整个表以保持简单。搜索合适的方法来调用就变得简单了。
<表>在C++标准中没有定义。这意味着编译器实现者可以自由地做任何他们想做的事情。甚至不能保证会有任何vtable。这是为什么我们没有C++ ABI的主要原因之一。告诉“说”的“每个人”。大概
Der1
Der2
每个人都有自己的vtable,不需要特别检查@Drop,是的,我知道。我没有提到我感兴趣的工具链规范是我的错误。这并不奇怪——GCC。新vtables将在何时何地出现?如果我错了,请纠正我:在编译时,Der1和Der2 vtables将被创建到RW数据部分;分配Base*obj1=new Der1时;通过obj1->func1()调用,Der1 vtable将被取消引用以查找该特定方法的条目。由于Base*obj1和obj2只是指针,它们没有并复制到vtable。因此,您能认可我对这一点的理解吗?否则我就错了?我不知道数据节,也不知道编译器/链接器如何准确地放置v表。从概念上讲,可以将V-TABLE视为全局链接列表。一个给定的类持有一个v形表头(因此类的大小由
sizeof(pointer)
添加)。派生类将创建另一个v表链表,而类(不是实例)将指向该链表。若派生类不重新定义虚函数,它将指向现有的v表链表。虚拟类层次结构可能指向多个这样的链表头,因此大小会增加。请看书/上网