3

以下のプログラムでは、基本クラス A の関数 'f' は、派生クラス B のオブジェクトに対して非表示になっています。しかし、B のオブジェクトを指している const A *d を介して関数 f を呼び出すと、基本クラスの関数 f は呼び出されます。ポインターの const 指定子 (つまり 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ます。したがって、非仮想を見つけますvoid f(int) const

ただし、これがある場合:

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

次に、fnon-const で検索されAます。そのため、が見つかりvirtual void f(int)、(実行時に) 最終的な overrider に委譲されますvoid B::f(int)

編集

これは、メンバー関数の選択に関する規則に従います。constパス (ポインターまたは参照)を介してアクセスする場合は、constメンバー関数のみが適用されます。非 const パスを介してアクセスする場合、非 const 関数が考慮されます。存在しない場合にのみ、ポインター (または参照) が暗黙的にポインター (または参照) に変換されconstconstメンバー関数が考慮されます。

于 2013-05-31T10:07:46.387 に答える