在以下程序中,功能' f'在基类A中隐藏了派生类B的对象。但是当我通过指向B的对象的const A * d调用函数f时,将调用来自基类的函数f。如果我删除指针(即A * d)函数的const说明符' f'从派生类调用。我的查询constness如何在这里有所作为?谢谢你的帮助。
#include <iostream>
class A
{
public:
virtual void f(int n) { std::cout << "A::f\n"; }
virtual ~A() { }
void f(int n) const { std::cout << "A::f const\n"; }
};
class B
: public A
{
public:
void f(int n) { std::cout << "B::f\n"; }
void f(int n) const { std::cout << "B::f const\n"; }
};
int main()
{
const A a;
B b;
A &c = b;
const A *d = &b;
c.f(1);
d->f(1);
return 0;
}
输出(带const A * d): B ::˚F A :: f const
输出(带A * d) B ::˚F B ::˚F
答案 0 :(得分:4)
要调用的函数的签名是在调用站点上根据指针的 static 类型确定的。然后在运行时选择此签名的正确覆盖。
换句话说,如果你有这个:
const A *d;
d->f(1);
然后在f
中搜索const A
。所以它找到了非虚拟的void f(int) const
。
但是,如果你有这个:
A *e;
e->f(1);
然后在非const f
中搜索A
。所以它找到virtual void f(int)
,然后(在运行时)委托给最终的覆盖者void B::f(int)
。
修改强>
这是关于成员函数选择的规则。通过const
路径(指针或引用)访问时,只有const
成员函数适用。通过非const路径访问时,会考虑非const函数。只有当没有时,指针(或引用)才会隐式转换为const
的指针(或引用),然后才会考虑const
成员函数。