using 声明是否应该隐藏继承的虚函数?

发布于 2024-10-11 14:51:06 字数 1000 浏览 9 评论 0原文

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

哪一个是正确的还是标准未定义的?

编辑: 这证明肯定存在错误,请考虑以下 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;
}

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

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

the above code using gcc gives

level2
level1

but in icc gives

 level2
 level2

Which one is correct or is it undefined by standard?

Edit:
This proves there is a bug for sure, consider the following main function

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

So the same object when used directly produces different results and when used via a pointer of same type produces different results!!!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

⒈起吃苦の倖褔 2024-10-18 14:51:06

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

这是一个已知的 g++ 错误

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

An example in Standard section 10.3p2 makes it clear that using declarations do not override virtual functions.

This is a known g++ bug.

As you noticed, when calling the member function via a reference or pointer, rather than a case in which the dynamic type is known, the bug does not happen.

遇到 2024-10-18 14:51:06

using level1::foo;level3 类中引入了 foo 函数,该函数引用 level1::foo

在用作成员声明的 using 声明中,嵌套名称说明符应命名所定义类的基类。这样的 using 声明引入了通过成员名称查找找到的声明集。

然而,由于 level1::foo 是虚拟的,我想通过调用它你应该调用 level2::foo ,因此 icc 应该是正确的。

无论如何,我不太确定。

using level1::foo; introduces a foo function in level3 class which refers to level1::foo.

In a using-declaration used as a member-declaration, the nested-name-specifier shall name a base class of the class being defined. Such a using-declaration introduces the set of declarations found by member name lookup.

However, since level1::foo is virtual, I guess that by calling it you should call level2::foo, thus icc should be right.

I'm not so sure, anyway.

白衬杉格子梦 2024-10-18 14:51:06

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

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

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

gcc 由于不一致而看起来错误,不确定 icc 因为我不知道标准表示什么。

The way to get level1 level1 of course would be:

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

Your "using" directive seems to be informing the compiler that if you have a level3 and call foo on it, it should invoke the level1 version, but it is not overwriting this to the v-table.

gcc looks wrong because of the inconsistency, not sure about icc because I don't know what the standard indicates.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文