C++親クラス間関数再定義、ダミー関数書き換え(上書き)、およびリロード
10659 ワード
この文章を書くとき、私はまだ再定義、書き直し(上書き)、重荷の間の正確な区別方法がよく分かりません.以下は私の今日の理解と関連するテストコードで、後で見ます!!第一に、単純なサブクラス再定義親メンバー関数(関数三要素:戻りタイプ、関数名、パラメータ):再定義である以上、関数名は同じに違いない.そうしないと、議論する必要はない.3つの要素はすべて同じで、自然に成立することができて、今の問題はタイプとパラメータを返して勝手に与えることができて、同じように親のメンバー関数を隠すことができますか?(1)関数名,戻りタイプ,パラメータともに同一
上の結果は、呼び出しサブクラスメンバー関数の出力:サブクラス(2)関数名、戻りタイプが同じ、パラメータが異なる、
1つのパラメータの場合、サブクラスのメンバー関数が呼び出され、出力は:サブクラスです.2つのパラメータの場合、ベースクラスメソッドが非表示になっていることを示します(継承関数を再定義し、元の関数が非表示になります).(3)継承メソッドを再定義し、元のプロトタイプと完全に一致することを確保する--戻りタイプコヒーレンス
出力結果エラー:書き換え虚関数の戻りタイプに違いがあり、「CBase::Walk」からのコヒーレントではありません.
第二:虚関数書き換え(上書き)(戻り値タイプは同じでなければならない)(1)パラメータリストは同じである
これは最も一般的な親の虚関数の書き換えです.
パラメータリストが異なります
虚関数を再定義しますが、パラメータリストが異なるため、関数の再ロードとして理解しやすいです.関数のリロードである場合、サブクラスオブジェクトは親がリロードされたメンバー関数を継承するべきである、ptr.Walk(2);間違いを報告すべきではない.これは、親クラスの同名関数が非表示になっていることを示します.
第三:親の再定義関数
結論:サブクラスは親関数を再ロードできません.すなわち、リロードは同じクラスで発生する
結論:クラス継承では、再定義、再ロードします.再定義関数名は同じで、戻りタイプは同じでなければなりません.パラメータリストは同じで、異なることができます.リロード、関数名は同じで、戻りタイプとパラメータのリストは少なくとも1つ異なります.子クラスに親と同じ名前の関数が表示されている限り、子クラスは親と同じ名前の関数(非表示)を継承しません.この同名の関数が親クラスで虚関数として宣言された場合(virtual)、書き換え(上書き)、虚関数でない場合、再定義と呼ばれます.
#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)、書き換え(上書き)、虚関数でない場合、再定義と呼ばれます.