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

哪一个是正确的,还是标准不确定?

编辑:这证明有一个错误,请考虑以下主要功能

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;
}

因此,当使用时,相同的对象会直接产生不同的结果,并且当通过相同类型的指针使用时,会产生不同的结果!!!

有帮助吗?

解决方案

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

这是一个 已知的G ++错误.

正如您注意到的那样,当通过参考或指针调用成员函数时,而不是知道动态类型的情况时,该错误不会发生。

其他提示

using level1::foo; 介绍 foo 功能在 level3 指的是 level1::foo.

在用作构件 - 陈述的使用范围中,嵌套名称的特定文件应命名为定义的类的基类。这样的使用 - 陈述介绍了成员名称查找的一组声明集。

但是,自从 level1::foo 是虚拟的,我想通过打电话给你应该打电话 level2::foo, ,因此ICC应该是正确的。

无论如何,我不太确定。

当然,获得Level1的方法当然是:

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

您的“使用”指令似乎在告知编译器,如果您有一个级别3并在其上调用foo,则应调用Level1版本,但并没有将其覆盖为V台。

海湾合作委员会由于不一致而看起来不正确,因此不确定ICC,因为我不知道标准所示。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top