English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
C++継承は単一継承または多重継承で、各継承接続はpublic、protected、private、virtualまたはnon virtualでできます。-virtual。次に、各メンバーファンクションのオプションはvirtualまたはnon virtualです。-virtualまたはpure virtual。この記事では、いくつかの重要なポイントを確認します。
public継承、例えば以下のようになります:
1 class base
2 {...}
3 class derived:public base
4 {...}
もしこんなように書くと、コンパイラはそのオブジェクトがderivedの型とbaseの型の両方を持っていると理解しますが、baseの型のオブジェクトはderivedの型を持っていません。これは非常に重要です。したがって、baseの型の引数を受け取る関数はderivedの型にも適用できますが、derivedの型の引数を受け取る関数はbaseの型には適用できません。以下は、baseの型の引数を持つ関数がderivedの型を引数に渡す場合の確認コードです。
#include <iostream> #include <stdio.h> class base { public: base() :baseName(""),baseData(0) {} base(std::string bn,int bd) :baseName(bn),baseData(bd) {} std::string getBaseName() const { return baseName; } int getBaseData()const { return baseData; } private: std::string baseName; int baseData; }; class derived:public base { public: derived():base(),derivedName("") {} derived(std::string bn,int bd,std::string dn) :base(bn,bd),derivedName(dn) {} std::string getDerivedName() const { return derivedName; } private: std::string derivedName; }; void show(std::string& info,const base& b) { info.append("Name is "); info.append(b.getBaseName()); info.append(", baseData is "); char buffer[10]; sprintf(buffer,"%d",b.getBaseData()); info.append(buffer); } int main(int argc, char* argv[]) { base b("test",10); std::string s; show(s,b); std::cout<<s<<std::endl; derived d("btest",5,"dtest"); std::string ss; show(ss,d); std::cout<<ss<<std::endl; return 0; }
実行結果は以下の通りです:
base:baseName is test, baseData is 10
base:baseName is btest, baseData is 5
以下のコードを変更し、関数の引数をderivedにします
void show2(std::string& info,const derived& d) { info.append("Name is "); info.append(d.getBaseName()); info.append(", baseData is "); char buffer[10]; sprintf(buffer,"%d",d.getBaseData()); info.append(buffer); }
show(ss,d);を呼び出したときにコンパイラがエラーを報告
1 derived_class.cpp: In function `int main(int, char**)': 2 derived_class.cpp:84: error: invalid initialization of reference of type 'const derived&' from expression of type 'base' 3 derived_class.cpp:70: error: in passing argument 2 of `void show2(std::string&, const derived&)
第二点では、さまざまな形の継承に対して確認を行います、まずテーブルを示します
継承方法\メンバーのタイプ | public | protected | private |
public | public | protected | 継承できません |
protected | protected | protected | 継承できません |
private | private | private | 継承できません |
ここでは説明します、ここでは基類のメンバーがpublic、protected、privateのいずれかの方法で継承された場合、元の基類のpublic、protected、privateのメンバーが継承クラスではテーブルの内容のタイプになります
class base { public: std::string testPublic() { return std::string("this is public base"); } protected: std::string testProtected() { return std::string("this is protected base"); } private: std::string testPrivate() { return std::string("this is private base"); } }; class derivedPublic:public base { public: std::string testPubPublic() { return testPublic()+= "in derived"; } std::string testProPublic() { return testProtected()+= "in derived"; } std::string testPriPublic() { return testPrivate()+= "in derived"; } }; int main(int argc, char* argv[]) { derivedPublic dpub; std::cout << dpub.testPublic() << std::endl; }
以下のエラーが報告され、testPrivate()がderivedのプライベート関数ではなくbaseのプライベート関数であることを示しています
derived11.cpp:16: エラー: `std::string base::testPrivate()` は private derived11.cpp:36: エラー: このコンテキスト内で
これでprivateタイプのメンバーが継承できないことを確認しました(public、private、protected)。注:private、protectedは証明を省略しています。
以下では、testProtectedが第三層の継承クラスで継承されるが、直接呼び出されないことを確認します。これは、protectedがpublic継承後の継承タイプであり、基類のPublicメンバーは継承されまた直接呼び出せることを示しています。
#include <iostream> #include <string> class base { public: std::string testPublic() { return std::string("this is public base"); } protected: std::string testProtected() { return std::string("this is protected base"); } private: std::string testPrivate() { return std::string("this is private base"); } }; class derivedPublic:public base { public: std::string testPubPublic() { return testPublic()+= "in derived"; } std::string testProPublic() { return testProtected()+= "in derived"; } // std::string testPriPublic() // { // return testPrivate()+= "in derived"; // } }; class deepDerived:public derivedPublic { public: std::string deepProtected() { return testProtected() +="in deep"; } std::string deepPublic() { return testPublic() +="indeep"; } }; int main(int argc, char* argv[]) { derivedPublic dpub; std::cout << dpub.testProtected() << std::endl; deepDerived deepdpub; std::cout << deepdpub.testPublic() << std::endl; std::cout << deepdpub.testProtected() << std::endl; std::cout << deepdpub.deepProtected() << std::endl; std::cout << deepdpub.deepPublic() << std::endl; }
ここでサーバーがエラーを報告しています
derived12.cpp:13: エラー: `std::string base::testProtected()` は protected derived12.cpp:62: エラー: このコンテキスト内で
これで、publicとprotectedの両方を確認しました。protectedは直接呼び出すことはできませんが、継承後はpublicメンバーとして呼び出すことができます。
以下の証明は省略されているが、詳細な手順に関心がある場合は以下のコードを参照してください。
#include <iostream> #include <string> class base { public: std::string testPublic() { return std::string("this is public base"); } protected: std::string testProtected() { return std::string("this is protected base"); } private: std::string testPrivate() { return std::string("this is private base"); } }; class derivedPublic:public base { public: std::string testPubPublic() { return testPublic()+= "in derived"; } std::string testProPublic() { return testProtected()+= "in derived"; } // std::string testPriPublic() //プライベートメンバーは継承されていません // { // return testPrivate()+= "in derived"; // } }; class deepDerived:public derivedPublic { public: std::string test() { return testPublic() +="in 3"; } }; class derivedProtected:protected base { public: std::string testPubProtected() { return testPublic()+= "in derived"; } std::string testProProtected() { return testProtected()+= "in derived"; } }; class deepDerived2:public derivedProtected { public: std::string test() { return testPublic() +="in 3"; } }; class derivedPrivate:private base { public: std::string testPubPirvate() { return testPublic()+= "in derived"; } std::string testProPrivate() { return testProtected()+= "in derived"; } }; //class deepDerived3:public derivedPrivate //{ // public: // std::string test() // { // return testPublic() +="in 3"; // } //}; int main(int argc, char* argv[]) { derivedPublic dpub; //derivedProtected dpro; //derivedPrivate dpri; std::cout << dpub.testPublic() << std::endl; // //std::cout << dpub.testProtected() << std::endl; //ユーザーが継承されていても使用できません //cout << dpub.testPrivate() << std::endl; //基底クラスはすべてプライベートな関数です std::cout<<dpub.testPubPublic()<<std::endl; std::cout<<dpub.testProPublic()<<std::endl; //std::cout<<dpub.testPriPrivate()<<std::endl; //継承されていません deepDerived dd; std::cout<<dd.test()<<std::endl; derivedProtected dpro; //std::cout<<dpro.testPublic()<<std::endl; //protected 类型に変更されました std::cout<<dpro.testPubProtected()<<std::endl; std::cout<<dpro.testProProtected()<<std::endl; deepDerived2 dd2; std::cout<<dd2.test()<<std::endl; derivedPrivate dpri; std::cout<<dpri.testPubPirvate()<<std::endl; std::cout<<dpri.testProPrivate()<<std::endl; // deepDerived3 dd3; // std::cout<<dd3.test()<<std::endl; }
これがC++ jが継承する資料の整理を行い、今後も関連する資料を追加していく予定です。皆様の本サイトへのサポートに感謝します!
声明:本文の内容はインターネットから取得され、著作権者に帰属します。インターネットユーザーにより自発的に提供されたコンテンツであり、本サイトは所有権を有しないです。人工的な編集は行われていません。また、関連する法的責任を負いません。著作権侵害の疑いがある場合は、以下のメールアドレスまでご連絡ください:notice#oldtoolbag.com(メール送信時、#を@に変更して報告してください。関連する証拠を提供し、一旦確認された場合、本サイトは即座に侵害疑いのコンテンツを削除します。)