匿名类的虚拟表

Gha*_*nPL 12 c++ virtual virtual-functions class anonymous-class

我的代码中有类似的东西:

#include <iostream>
#include <cstdlib>

struct Base
{
  virtual int Virtual() = 0;
};

struct Child
{
  struct : public Base
  {
    virtual int Virtual() { return 1; }
  } First;

  struct : public Base
  {
    virtual int Virtual() { return 2; }
  } Second;
};

int main()
{
  Child child;
  printf("ble: %i\n", ((Base*)&child.First)->Virtual());
  printf("ble: %i\n", ((Base*)&child.Second)->Virtual());

  system("PAUSE");
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

我希望这会给出这个输出:

ble: 1
ble: 2
Run Code Online (Sandbox Code Playgroud)

当它在GCC下编译时(3.4.5我相信).

但是,在Visual Studio 2008下编译并运行它,可以得到:

ble: 2
ble: 2
Run Code Online (Sandbox Code Playgroud)

有趣的是,如果我给出Base-derived structs names(struct s1 : public Base),它就可以正常工作.

哪种行为(如果有的话)是正确的?VS只是娇小,还是坚持标准?我错过了一些重要的东西吗?

小智 7

看起来这是VS 2008中的一个错误,可能是因为它覆盖或忽略了第一个未命名类的vtable而支持第二个vtable,因为内部名称是相同的.(当您明确命名一个时,vtable的内部名称不再相同.)

据我所知,从标准来看,这应该像你期望的那样工作,而gcc是正确的.


Han*_*ant 2

从调试符号中可以看出 MSVC 是如何出错的。它分别为匿名结构生成临时名称Child::<unnamed-type-First>Child::<unnamed-type-Second>。然而,只有一个 vtable,它被命名Child::<unnamed-tag>::'vftable'并且两个构造函数都使用它。vtable 的不同名称肯定是该错误的一部分。

Connection.microsoft.com 上报告了几个与匿名类型相关的错误,但没有一个达到“必须修复”状态。不过,这不是你找到的那个。也许解决方法太简单了。