【问题标题】:Is virtual table per object or per class? [duplicate]虚拟表是每个对象还是每个类? [复制]
【发布时间】:2015-07-08 18:21:09
【问题描述】:

谁能告诉我虚拟表和虚拟指针是每个类还是每个对象?如果它们是每个对象的,为什么不能在同一类的对象之间共享它们,而不是为每个对象维护一个副本?

【问题讨论】:

  • 虚拟表是共享的,指向表的指针是每个对象的。如果你想知道为什么,我很确定这个问题已经在这个网站上讨论过
  • 在典型的实现中,它是每个类的,但它是一个实现细节,因此标准没有要求。
  • stackoverflow.com/questions/25463790/… 不是 100% 重复,但仍然相关
  • 拥有虚拟继承会使它复杂化。
  • @DieterLücking 拥有虚拟继承仍然会为每个类而不是每个对象生成一个虚拟表!

标签: c++


【解决方案1】:

它是实现定义的,但它通常是每个类的静态 vtable,并且每个实例都有一个指向该类的 vtable 的 vptr。每个实例都需要指针的原因是因为编译器在编译时可能不知道特定变量将是哪个具体实现,因此指向相关 vtable 的指针必须可以从引用中确定地访问。因此,拥有一个 vtable 的全部意义在于 :)

【讨论】:

  • 不,不是!虚拟表始终按班级分配。可能存在为每个对象携带一个虚拟表的实现,但是,如果您修改实例的虚拟表,则您正在更改该实例的类。当你改变实例的行为,因为实例的行为定义了类时,你不能说一个实例属于一个类。
  • @ikrabbe 这个答案说“它通常是每个类的静态vtable,并且每个实例都有一个指向该类的vtable的vptr”。这是真的,而且这似乎也是你所声称的。事实上,您在自己的回答中举了一个例子。那么,有什么问题呢?
  • 问题是虚拟指针这个词似乎和虚拟表存在于同一个域中,但是虚拟指针,实际上是指向虚拟表的指针,是一个实现细节,而虚拟函数表是导致面向对象编程的微积分的一部分。这个词很混乱。实际上,如果你计算程序中不同的虚拟指针,你就会计算程序使用的不同类。
【解决方案2】:

没错。每个类都有一个虚拟表,否则将毫无意义。虚拟指针什么都不是。不要使用这个词!

Virtual Pointer

扔掉你的 C++,想想用 C 来实现它吧:

typedef VirtualFunctionsOfAClass AClassesVTable
struct AClass {
    some_data
    AClassesVTable *vptr;
};
struct VirtualFunctionsOfAClass {
     int(*someFunc1)(struct AClass* _This, int a);
     int(*anotherFunc1)(struct AClass* _This, int a);
};

static AClassesVTable vtableOfClassA = {func1, func2};

struct AClass* constructAClass() {
    AClass* ac=malloc(sizeof(AClass));
    ac->vptr = &vtableOfClassA;
    return ac;
}

void aNonVirtualMemberFunctionOfClassA(AClass* _This, more arguments)
{
     return; /* just a dummy */
}

是的:使用纯 C,您可以将函数指针分配给每个对象。但这与 C++ 中的虚函数不同。

【讨论】:

  • "扔掉你的 C++,想想它会如何用 C 实现" 什么
  • 虚拟表和成员函数
  • 谁曾否决这个答案:你错了!如果您为每个实例定义一个虚拟表,OO 绝对没有意义。
  • 他们可能因为“虚拟指针什么都不是”的废话和不必要的 C 寓言而否决了它。考虑实现细节,尤其是发明的细节,在 C++ 中没有用。 C++ 是一种抽象。抽象地思考一下。
  • 虚拟指针这个词是一个非常糟糕的词。它具有误导性,并且没有实现这种东西的概念。从下面的 cmets 中: __vptr 不是指虚拟指针,而是指向虚拟表的指针。当您使用普通的 ansi C 实现类逻辑时,可以看到指向虚拟表的指针,因为 C++ 编译器对程序员隐藏了这一点。除了上面的 C 代码中显示的之外,没有 C++ 或任何其他子方言(C#、Objective-C)实现虚函数。如果你发现一些实现与上面代码的方案不匹配,我会修复答案。
【解决方案3】:

虚拟表是每个班级的。虚拟指针是每个对象。看这里http://www.go4expert.com/articles/virtual-table-vptr-t16544/

【讨论】:

  • 虚拟指针这个词没有意义。 _vptr 是指向虚拟表的指针。当然,每个对象都需要对类的虚拟表的引用。所以每个带有虚拟表的对象都需要一个指向该类的虚拟表的指针。但它为类的每个对象指向同一个虚拟表。所以虚拟指针什么都不是,_vptr 对于类的每个对象肯定具有相同的值!
  • @ikrabbe _vptr 是标准术语吗?否则,“虚拟表指针”或“vtable 指针”可能是一个更好的术语
  • 我只是从链接中使用它。是的:虚拟指针什么也没说。它是 vtable 或虚拟表指针,甚至是“指向虚拟表的指针”。正如我所说:术语虚拟指针是")(§"$/%=)。顺便提一句。请参阅我关于虚拟指针的答案中的链接!
  • 有时候这个网站上有很多迂腐 :) vptr 是一个非常标准的书面术语,很多人使用术语“虚拟指针”来指代它。 “虚拟指针”与“虚拟表”一样有意义(该表不是虚拟的,它在技术上更称为虚拟方法表或调度表),归根结底,大多数程序员都足够聪明地知道您在上下文中所说的内容。
猜你喜欢
  • 1970-01-01
  • 2010-10-08
  • 2017-10-27
  • 2015-10-26
  • 2013-02-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-06
相关资源
最近更新 更多