3

在下面的程序中,基类A中的函数'f'对于派生类B的对象是隐藏的。但是当我通过指向B的对象的const A *d调用函数f时,来自基类的函数f是被调用。如果我从派生类中删除指针(即A * d)函数'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

4

1 回答 1

4

要调用的函数的签名是在调用站点上根据指针的静态类型确定的。然后在运行时选择此签名的正确覆盖器。

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

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

然后在f中搜索const A。所以它找到了 non-virtual void f(int) const

但是,如果你有这个:

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

然后f在 non-const 中搜索A。所以它会找到virtual void f(int),然后(在运行时)委托给最终的 overrider void B::f(int)

编辑

这遵循关于成员函数选择的规则。通过const路径(指针或引用)访问时,只有const成员函数适用。通过非常量路径访问时,会考虑非常量函数。只有在没有指针(或引用)的情况下才会隐式转换为指向的指针(或引用)const,然后const才考虑成员函数。

于 2013-05-31T10:07:46.387 回答