C++親クラス間関数再定義、ダミー関数書き換え(上書き)、およびリロード

10659 ワード

この文章を書くとき、私はまだ再定義、書き直し(上書き)、重荷の間の正確な区別方法がよく分かりません.以下は私の今日の理解と関連するテストコードで、後で見ます!!第一に、単純なサブクラス再定義親メンバー関数(関数三要素:戻りタイプ、関数名、パラメータ):再定義である以上、関数名は同じに違いない.そうしないと、議論する必要はない.3つの要素はすべて同じで、自然に成立することができて、今の問題はタイプとパラメータを返して勝手に与えることができて、同じように親のメンバー関数を隠すことができますか?(1)関数名,戻りタイプ,パラメータともに同一
#include 
using namespace std;
class CBase
{
public:
    void my(int a){
        cout << "  " << endl;
    }
};
class CDerivedA : public CBase
{
public:
    void my(int a ){
        cout << "  " << endl;//     ,   ,    ,     
    }
};
int main()
{
    CDerivedA ptr;
    ptr.my(5);
    system("pause");
    return 0;
}

上の結果は、呼び出しサブクラスメンバー関数の出力:サブクラス(2)関数名、戻りタイプが同じ、パラメータが異なる、
#include 
using namespace std;
class CBase
{
public:
    void  my(int a,int b){
        cout << "  " << endl;
    }
};
class CDerivedA : public CBase
{
public:
    void my(int a ){
        cout << "  " << endl;//      
    }
};
int main()
{
    CDerivedA ptr;
    ptr.my(5);//(1)      
    ptr.my(5,5);//(2)      ,     ,         。      ,          void my(int a,int b)  。
    system("pause");
    return 0;
}

1つのパラメータの場合、サブクラスのメンバー関数が呼び出され、出力は:サブクラスです.2つのパラメータの場合、ベースクラスメソッドが非表示になっていることを示します(継承関数を再定義し、元の関数が非表示になります).(3)継承メソッドを再定義し、元のプロトタイプと完全に一致することを確保する--戻りタイプコヒーレンス
#include 
using namespace std;
class CBase
{
public:
    void  my(int a,int b){
        cout << "  " << endl;
    }
    virtual void Walk(){ cout << "CBase:Walk" << endl; }
};
class CDerivedA : public CBase
{
public:
    void my(int a ){
        cout << "  " << endl;
    }
    int  Walk(){ cout << "CDerivedA:Walk" << endl; }//             
};
int main()
{
    CDerivedA ptr;
    ptr.Walk();
    system("pause");
    return 0;
}

出力結果エラー:書き換え虚関数の戻りタイプに違いがあり、「CBase::Walk」からのコヒーレントではありません.
第二:虚関数書き換え(上書き)(戻り値タイプは同じでなければならない)(1)パラメータリストは同じである
#include 
using namespace std;
class CBase
{
public:
    void  my(int a,int b){
        cout << "  " << endl;
    }
    virtual void Walk(){ cout << "CBase:Walk" << endl; }
};
class CDerivedA : public CBase
{
public:
    void my(int a ){
        cout << "  " << endl;
    }
    void Walk(){ cout << "CDerivedA:Walk" << endl; }//  
};
int main()
{
    CDerivedA ptr;
    ptr.Walk();//     :CDerivedA:Walk
    system("pause");
    return 0;
}

これは最も一般的な親の虚関数の書き換えです.
パラメータリストが異なります
#include 
using namespace std;
class CBase
{
public:
    void  my(int a,int b){
        cout << "  " << endl;
    }
     virtual void Walk(int a){ cout << "CBase:Walk" << endl; }
};
class CDerivedA : public CBase
{
public:
    void my(int a ){
        cout << "  " << endl;
    }
    void  Walk(){ cout << "CDerivedA:Walk" << endl; }//  
};
int main()
{
    CDerivedA ptr;
    ptr.Walk(2);//  :      1    
    ptr.Walk();//  :CDerivedA:Walk
    system("pause");
    return 0;
}

虚関数を再定義しますが、パラメータリストが異なるため、関数の再ロードとして理解しやすいです.関数のリロードである場合、サブクラスオブジェクトは親がリロードされたメンバー関数を継承するべきである、ptr.Walk(2);間違いを報告すべきではない.これは、親クラスの同名関数が非表示になっていることを示します.
第三:親の再定義関数
#include 
using namespace std;
class CBase
{
public:
    void  my(int a,int b){
        cout << "  " << endl;
    }
     virtual void Walk(int a){ cout << "CBase:Walk" << endl; }
     virtual void Walk(){ cout << "CBase::::::Walk" << endl; }
};
class CDerivedA : public CBase
{
public:
    void my(int a ){
        cout << "  " << endl;
    }
    //void  Walk(){ cout << "CDerivedA:Walk" << endl; }//  
};
int main()
{
    CDerivedA ptr;
    ptr.Walk(2);//  :CBase:Walk
    ptr.Walk();//  :CBase::::::Walk
    system("pause");
    return 0;
}

結論:サブクラスは親関数を再ロードできません.すなわち、リロードは同じクラスで発生する
結論:クラス継承では、再定義、再ロードします.再定義関数名は同じで、戻りタイプは同じでなければなりません.パラメータリストは同じで、異なることができます.リロード、関数名は同じで、戻りタイプとパラメータのリストは少なくとも1つ異なります.子クラスに親と同じ名前の関数が表示されている限り、子クラスは親と同じ名前の関数(非表示)を継承しません.この同名の関数が親クラスで虚関数として宣言された場合(virtual)、書き換え(上書き)、虚関数でない場合、再定義と呼ばれます.