通过指向const基类的指针调用虚函数

calling virtual function through pointer to const base class

本文关键字:指针 调用 函数 基类 const      更新时间:2023-10-16

在下面的程序中,基类A中的函数'f'对于派生类B的对象是隐藏的,但是当我通过指向B对象的const A *d调用函数f时,基类中的函数f被调用。如果我删除指针的const说明符(即A *d)函数'f'从派生类被调用。我的问题是这里的常数是如何产生影响的?谢谢你的帮助。

#include <iostream>
class A
{
public:
    virtual void f(int n) { std::cout << "A::fn"; }
    virtual ~A() { }
    void f(int n) const { std::cout << "A::f constn"; }
};
class B
    : public A
{
public:
    void f(int n) { std::cout << "B::fn"; }
    void f(int n) const { std::cout << "B::f constn"; }
};
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答::f const

输出(带A* d)B: fB: f

要调用的函数的签名在调用现场根据指针的static类型确定。然后在运行时选择此签名的正确重写。

换句话说,如果你有这个:

const A *d;
d->f(1);

则在const A中搜索f。所以它找到了非虚拟的void f(int) const

但是,如果你有这个:

A *e;
e->f(1);

则在非const A中搜索f。因此,它找到virtual void f(int),然后(在运行时)将其委托给最终的覆盖void B::f(int)

编辑

这是成员函数选择的规则。当通过const路径(指针或引用)访问时,只适用const成员函数。当通过非const路径访问时,会考虑使用非const函数。只有当不存在时,指针(或引用)才隐式地转换为指向const的指针(或引用),然后才考虑const成员函数。