2
void f()
{}

struct A
{
    void f()
    {}
};

struct B : A
{
    B()
    {
        f(); // A::f() is always called, and ::f is always ignored 
    }
};

int main()
{
    B();
}

classBの設計者として、 がB基本クラスである、つまりAがメンバー関数を持っているという事実を知らないかもしれませんが、私A::fは知っているだけ::fで、呼び出し::fはまさに私が望むものです。

私が期待しているのは、呼び出しのあいまいさのためにコンパイラがエラーを出すことfです。ただし、コンパイラは常に を選択A::fして無視し::fます。これは大きな落とし穴になるのではないかと思います。

私はただ疑問に思います:

メンバー関数のオーバーロード解決でグローバル関数が除外されるのはなぜですか?

根拠は何ですか?

4

2 に答える 2

4

クラス B の設計者として、私は B の基本クラスを知らないかもしれません

同意しません。

メンバー関数のオーバーロード解決でグローバル関数が除外されるのはなぜですか?

2 つのオーバーロードは 2 つの異なるスコープに属し、コンパイラは同じスコープのオーバーロードを選択するためです。§3.4.1 を読む。f内側 (同じ) スコープの は、外側の を非表示にしますf

根拠は何ですか?

しっかりとしたルールを持つこと。私たちは同じ範囲で作業することを好みます。明示的に別の場所からオブジェクトを呼び出したい場合を除きます。

アレックスに電話する家族では、マケドニアのアレクサンダー3世ではなく、小さな男の子のアレックスが来ることを期待しています。

于 2013-10-26T08:45:18.110 に答える
4

それがオーバーロード解決の仕組みであり、良いことです。

本当に大きなプロジェクト、大量の相互依存関係、サードパーティのコード、クロスモジュール インクルードがあると想像してみてください。この巨大な混乱の中で、機能することがわかっているクラスが 1 つあります。5 年間完璧に機能しており、効率的で読みやすく、きれいです。あなたはそれに触れたくありません。その後、モジュールをアップグレードすると、コンパイラ エラーが発生し始めます。大野!そのモジュール (制御できない)DoAmazingStuff()は、グローバル名前空間に新しい関数を導入しました。クラスのメソッド名と同じです。クラスメンバーに同じ名前を使用できなくなったため、リファクタリングする必要があります。残念!

于 2013-10-26T08:50:18.497 に答える