using 声明是否应该隐藏继承的虚函数?
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
标准第 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.
using level1::foo;
在level3
类中引入了foo
函数,该函数引用level1::foo
。然而,由于
level1::foo
是虚拟的,我想通过调用它你应该调用level2::foo
,因此 icc 应该是正确的。无论如何,我不太确定。
using level1::foo;
introduces afoo
function inlevel3
class which refers tolevel1::foo
.However, since
level1::foo
is virtual, I guess that by calling it you should calllevel2::foo
, thus icc should be right.I'm not so sure, anyway.
当然,获得 level1 level1 的方法是:
您的“using”指令似乎是在通知编译器,如果您有 level3 并在其上调用 foo,它应该调用 level1 版本,但它不会将其覆盖到 v -桌子。
gcc 由于不一致而看起来错误,不确定 icc 因为我不知道标准表示什么。
The way to get level1 level1 of course would be:
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.