【问题标题】:Is a using-declaration supposed to hide an inherited virtual function?使用声明是否应该隐藏继承的虚函数?
【发布时间】:2011-06-07 20:36:20
【问题描述】:
struct level0
{
  virtual void foo() = 0;
};

struct level1 : level0
{
  virtual void foo() { cout <<" level1  " << endl; }
};

struct level2 : level1
{
  virtual void foo() { cout <<" level2 " << endl; }
};

struct level3 : level2
{
  using level1::foo;
};

int main()
{
  level1* l1 = new level3;
  l1->foo();
  level3 l3;
  l3.foo();
  return 0;
}

上面使用gcc的代码给出了

level2
level1

但在icc中给出了

 level2
 level2

哪个是正确的还是没有标准定义?

编辑: 这证明肯定有bug,考虑下面的main函数

int main()
{
    level3 l3;
    l3.foo();               // This prints level1

    level3* pl3 = &l3;
    pl3->foo();             // This prints level2

    level3& rl3 = l3;
    rl3.foo();              // This prints level1

    level3& rpl3 = *pl3;
    rpl3.foo();             // This prints level2

    return 0;
}

所以同一个对象直接使用会产生不同的结果,通过相同类型的指针使用会产生不同的结果!!!

【问题讨论】:

  • 我猜 GCC 是正确的,但我不确定。
  • 我已确认 TDM MinGW g++ 4.4.1 的行为。这是一个 g++ 错误,请报告它。干杯&hth.,
  • 有趣的是,我昨天刚研究过这个。
  • 这已在 GCC 4.8 中修复。

标签: c++ inheritance gcc icc using-declaration


【解决方案1】:

标准第 10.3p2 节中的一个示例清楚地表明,使用声明不会覆盖虚函数。

这是known g++ bug

正如您所注意到的,当通过引用或指针调用成员函数时,而不是在动态类型已知的情况下,不会发生错误。

【讨论】:

  • +1 用于标准报价,至于错误:2004 年报告,2006 年最后一次更新 --> 我想没有人真正关心,因为它很容易解决:)
【解决方案2】:

using level1::foo; 在引用level1::foolevel3 类中引入了foo 函数。

在用作成员声明的 using-declaration 中,nested-name-specifier 应命名所定义类的基类。这样的 using-declaration 引入了通过成员名称查找找到的一组声明。

不过,既然level1::foo是虚拟的,我想调用它应该调用level2::foo,所以icc应该是对的。

反正我也不是很确定。

【讨论】:

    【解决方案3】:

    获得level1 level1的方法当然是:

    struct level3 : level2
    {
       virtual void foo() { level1::foo(); }
    };
    

    您的“using”指令似乎是在通知编译器,如果您有一个 level3 并在其上调用 foo,它应该调用 level1 版本,但它不会将其覆盖到 v-table。

    gcc 看起来不对,因为不一致,不确定 icc,因为我不知道标准表示什么。

    【讨论】:

      猜你喜欢
      • 2014-06-29
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 1970-01-01
      • 2017-07-12
      • 1970-01-01
      • 2013-09-26
      • 1970-01-01
      相关资源
      最近更新 更多