首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在派生类中使用-声明不会隐藏从基类派生的相同函数。

在派生类中使用-声明不会隐藏从基类派生的相同函数。
EN

Stack Overflow用户
提问于 2015-02-11 08:03:23
回答 1查看 566关注 0票数 25

请看以下代码:

代码语言:javascript
复制
struct A {
public:
    virtual void f(){std::cout << "in A";};
};

struct B : A{
public:
   virtual void f(){std::cout << "in B";};
   int a;
};

struct C : B{
    using A::f;
    void test(){f();}
};


int main() 
{
    C c;
    c.f(); // calls B::f, the final overrider
    c.C::f(); // calls A::f because of the using-declaration
    c.test(); //calls B::f
    return 0;
}

根据我的理解,B::f() in C应该隐藏通过使用-声明而带到CA::f();如果是这样的话,为什么c.C::f()仍然调用A::f()

如果c.C::f()调用A::f(),这意味着在C的范围内,f()应该总是引用A::f(),这是using-声明的函数。那么为什么在C::test()中,对f()的调用仍然被计算为B::f()

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2015-02-11 08:14:53

很好的问题,一个复杂的名字查找案例。

基本上,当在f的作用域中查找名称C时,由于使用声明,它总是会找到A::f。因此,所有调用c.f()c.C::f()f()C::test(),将名称f解析为A::f

接下来是虚拟调度。如果以不限定的名称调用虚拟函数,则会发生动态调度,并调用最终的覆盖器。这包括c.f()C::test()中的f()调用,因为它们是不合格的。

调用c.C::f()使用f的限定名,这将抑制动态调度,并直接调用名称解析的函数。由于该函数是A::f (由于使用-声明),所以A::f被称为非虚拟函数。有关规则如下(引用C++14最后草案N4140,重点是地雷):

§10.3/15

使用作用域运算符(5.1)的显式限定将取消虚拟调用机制。

§5.2.2/1

..。如果所选函数为非虚拟函数,则为,或者如果类成员访问表达式中的是限定-id,则调用该函数。否则,调用对象表达式的动态类型中的最终覆盖器(10.3);这样的调用称为虚拟函数调用。

票数 29
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/28449304

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档