3

最近、これを知りました-派生クラスが基本クラスのメンバーメソッドを再定義すると、同じ名前のすべての基本クラスメソッドが派生クラスに隠されます。

#include<iostream>

using namespace std;

class Base
{
public:
int fun()
{
    cout<<"Base::fun() called";
}
int fun(int i)
{
    cout<<"Base::fun(int i) called";
}
};

class Derived: public Base
{
public:
int fun() 
{
    cout<<"Derived::fun() called";
}
};

int main()
{
Derived d;
d.fun(5);  // Compiler Error
return 0;
}

エラー : 関数 'int main()' 内: 行 30: エラー: 'Derived::fun(int)' の呼び出しに一致する関数がありません -Wfatal-errors によりコンパイルが終了しました。

しかし、その背後にある理由を知りたいですか?Derived クラスは Base から派生しているため、Base Class の fun(int i) メソッドを呼び出さないのはなぜですか

4

2 に答える 2

5

基本的な理由は、コードをより堅牢にすることです。

struct Base {
};

struct Derived : Base {
    void f(long);
    void g() { f(3); } // calls Derived::f
}

ここBaseで、 がライブラリで定義されているとします。そのライブラリが更新され、更新によって の定義が変更されますBase

struct Base {
    void f(int);
};

ここで、オーバーロードされた関数の検索が、名前が見つかったときに停止しなかったとします。その場合、はの代わりにDerived::g呼び出され、派生クラスは以前とはまったく異なること、および設計および文書化されたものとは異なることを静かに行います。Base::fDerived::f

于 2013-04-08T13:59:57.693 に答える
2

派生クラスのオーバーロードが、同じ名前でパラメーターが異なる基本クラスのメソッドをシャドーする (可視性を妨げる) ことは既にわかっています。これが何らかの歴史的または認識された安全上の理由で行われたと主張して、修正を見てみましょう。

class Derived: public Base
{
public:
  using Base::fun; // expose the base-class method
  int fun() 
  {
    cout<<"Derived::fun() called";
  }
};
于 2013-04-08T13:55:40.023 に答える