English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C++ 継承の詳細と実例コード

 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(メール送信時、#を@に変更して報告してください。関連する証拠を提供し、一旦確認された場合、本サイトは即座に侵害疑いのコンテンツを削除します。)

基礎教程