複数の継承を持つオーバーロードされた関数
C では、関数のオーバーロードを使用すると、同じ名前の複数の関数を単一のスコープ内で定義できます。それらには異なるパラメータリストがあります。ただし、この動作は、名前は同じでシグネチャが異なる複数の継承関数には適用されません。これにより、次のような疑問が生じます: なぜそのような関数はオーバーロードとして扱われないのですか?
C 標準のセクション 10.2/2 によると、メンバー検索ルールにより、名前検索中に非表示の宣言が考慮から除外されることが規定されています。複数の基本クラスが同じ名前で異なるパラメーターを持つ関数を定義する場合、これらの関数は相互に隠蔽される可能性があります。したがって、結果の宣言セットが同じ型のサブオブジェクトからのものではない場合、または非静的メンバーと異なるサブオブジェクトからのメンバーが含まれている場合、あいまいさが生じ、プログラムは不正な形式であるとみなされます。
例:
class A { public: int f(int); }; class B { public: int f(); }; class C : public A, public B {};
この場合、 f は 2 つの異なる基本クラス (A と B) で定義されているため、あいまいです。したがって、C クラスからの f への次の呼び出しは正しくありません。
int main() { C c; c.f(); // ambiguous }
この曖昧さを解決するには、using 宣言を使用して、どの基本クラスが f 関数を実装するかを指定できます。例:
class C : public A, public B { using A::f; using B::f; };
この変更により、c.f() はクラス A から f を明示的に呼び出し、曖昧さを解決するようになりました。
対照的に、foo(float) が定義されているため、提供した 2 番目のコード例は機能します。派生クラスのスコープ内にあり、複数の基本クラスから継承されません。したがって、 d.foo(5) は、曖昧さなく foo(float) 関数を直接呼び出します。
免責事項: 提供されるすべてのリソースの一部はインターネットからのものです。お客様の著作権またはその他の権利および利益の侵害がある場合は、詳細な理由を説明し、著作権または権利および利益の証拠を提出して、電子メール [email protected] に送信してください。 できるだけ早く対応させていただきます。
Copyright© 2022 湘ICP备2022001581号-3