C++Exceptionalクラスのリロード、書き換え(上書き)、非表示

3529 ワード

次の例では、リロード、書き換え(上書き)、および非表示の関係をよく理解できます.
class Base
{
public:
    virtual ~Base() {}
    virtual void f(int);
    virtual void f(double);
    virtual void g(int i = 10);
};
void Base::f(int)
{
    cout << "Base::f(int)" << endl;
}

void Base::f(double)
{
    cout << "Base::f(double)" << endl;
}

void Base::g(int i)
{
    cout << "Base::g(int)" << i << endl;
}

class Derived : public Base
{
public:
    void f(complex<double>);
    void g(int i = 20);
};

void Derived::f( complex<double> )
{
    cout << "Derived::f(complex)" << endl;
}

void Derived::g(int i)
{
    cout << "Derived::g()" << i << endl;
}

int main(int argc, char * argv[])
{
    Base b;
    Derived d;
    Base* pb = new Derived;
    b.f(1.0);
    d.f(1.0);
    pb->f(1.0);
    b.g();
    d.g();
    pb->g();
    delete pb;
}

以下、以上のプログラムの出力をそれぞれ説明する:1.b.f(1.0) Base::f(double) 2. d.f(1.0) Derivedf(complex) 3. pb->f(1.0) Base::f(double) 4. b.g() Base::g(int) 10 5. d.g() Derived::g(int) 20 6. pb->g() Derived::g(int) 10
リロード:Baseのf(int)f(double)はリロード関係であり、リロードは同じクラスで同じ関数名を持つが、関数パラメータは異なる.
書き換え(上書き):Derivedのg(int i = 20)はベースクラスBaseのg(int i = 10)を書き換えたが、ここではサブクラスを指すベースクラスポインタでg(int)を呼び出すと、デフォルトのパラメータは静的バインドであり、つまりベースクラスBaseのi = 10は静的バインドであるため、6はDerived::g(int)10を出力する
非表示:Derivedのf( complex )は、サブクラスの同じ名前の関数を非表示にします.パラメータが異なるため、ここは書き換えではありません.ただし、子クラスの関数は、親クラスの同名の関数を非表示にします.したがって,2 3の出力はそれぞれ上記のようになる.pb->f(1.0)はDerivedのf(complex)関数を呼び出すわけではありません.この2つの関係は書き換えではなく、非表示なので、呼び出されたのはBaseの関数です.