〜〜 C++講座・JAVA講座・VB講座・ネット収入講座・アフィリエイト講座・メール受信講座・株講座・投資信託講座・お小遣い講座 〜〜

   MENU           == C++基本講座 ==

1. はじめに
2. オブジェクト指向
3. 文法関連
4. クラス
5. コンストラクタ/デストラクタ
6. オーバーライド(仮想関数)
7. オーバーロード
8. new/delete
9. 継承/多重継承
10. 例外処理
11. inline関数,static変数



 得@スキルアップ塾.com > C++基本講座 > 9. 継承/多重継承

   継承/多重継承


■講義一覧
 1. 概要
 2. 継承(public)
 3. 多重継承(仮想定義virtual)


■1.概要

 ・継承とは、ある機能を持ったクラスAに対して、同様で且つ追加機能を持つクラスBがある場合、
  クラスAを親クラスとして継承し、クラスBを子クラスとして定義することを言います。

 ・一般的に親クラスのことを、基底クラス、スーパークラスと言い、
  子クラスのことを、サブクラス、派生クラスと言われています。

一覧へ

■2.継承

 ・クラス宣言時に、"public"キーワードを定義することで継承関係を定義します。

一覧へ

■3.多重継承

 ・多重継承とは、基底クラス→派生クラス→派生クラスといったように、継承を繰り返すこと指します。

 ・ただ、多重継承を取り入れた場合、基底クラスが同一の派生クラスをそれぞれ継承した場合、
  想定どおりに動作しない場合あるので注意して下さい。

【継承クラス】
// 継承

//J 基底クラス(A)

class A{
  public:
  int data;

  
//J コンストラクタ
  A(){
   printf(
"Aクラスのコンストラクタ\n");
   data = 0;
  }
};

//J 派生クラス(B)

class B :
public A{

 //J 基底クラスAのdataを+1する
 public:
 B(){
  printf(
"Bクラスのコンストラクタ\n");
 }
 void plus(){
  data++;
 }

};
//J 派生クラス(C)
class C :
public A{

 //J 基底クラスAのdataを+1する
 public:
 C(){
  printf(
"Cクラスのコンストラクタ\n");
 }
 void plus(){
  data++;
 }
};

//J 派生クラス(D)
class D :
public B,public C{

 public:

 D(){
  printf(
"Dクラスのコンストラクタ\n");
 }

};


【呼び出し側】
void main(){

@ D ob_d;

  ob_d.B::plus();
  ob_d.C::plus();
  ob_d.B::plus();

A printf("ob_d.data = %d\n",ob_d.B::data);
B printf("ob_d.data = %d\n",ob_d.C::data);


}

@コンストラクタで継承された全てのコンストラクタが動作する。出力内容は以下のとおり
・"Aクラスのコンストラクタ"
・"Bクラスのコンストラクタ"
・"Aクラスのコンストラクタ" ※注意 Aクラスのコンストラクタが2度呼ばれている 
・"Cクラスのコンストラクタ"
・"Dクラスのコンストラクタ"

A出力結果は"ob_d.data = 2"と表示
B出力結果は"ob_d.data = 1"と表示


ここで注目すべきことは、基底クラスが同一のクラスを多重継承した場合、継承したクラスそれぞれに
メモリ領域を確保するため、あいまいさが生じてしまいます。




どのような仕様にもよりますが、基底クラスのdata変数に関しては、共通的に更新したといった場合、
C++言語においては、仮想定義(virtualキーワード)をすることで対応ができます。

【多重継承クラス(仮想定義)】
// 多重継承

//J 基底クラス(A)

class A{
  public:
  int data;

  
//J コンストラクタ
  A(){
   printf(
"Aクラスのコンストラクタ\n");
   data = 0;
  }
};

//J 派生クラス(B)

class B :
virtual public A{

 //J 基底クラスAのdataを+1する
 public:
 B(){
  printf(
"Bクラスのコンストラクタ\n");
 }
 void plus(){
  data++;
 }

};
//J 派生クラス(C)
class C :
virtual public A{

 //J 基底クラスAのdataを+1する
 public:
 C(){
  printf(
"Cクラスのコンストラクタ\n");
 }
 void plus(){
  data++;
 }
};

//J 派生クラス(D)
class D : public B,public C{

 public:

 D(){
  printf(
"Dクラスのコンストラクタ\n");
 }

};


【呼び出し側】
void main(){

@ D ob_d;

  ob_d.B::plus();
  ob_d.C::plus();
  ob_d.B::plus();

A printf("ob_d.data = %d\n",ob_d.B::data);
B printf("ob_d.data = %d\n",ob_d.C::data);


}

@コンストラクタで継承された全てのコンストラクタが動作する。出力内容は以下のとおり
・"Aクラスのコンストラクタ"
・"Bクラスのコンストラクタ"
・"Cクラスのコンストラクタ"
・"Dクラスのコンストラクタ"
※Aクラスのコンストラクタが1度しか呼ばれなくなった

A出力結果は"ob_d.data = 3"と表示
B出力結果は"ob_d.data = 3"と表示


Aクラスのdata変数は、Bクラス経由でもCクラス経由でも、同じアドレスを指しようになり、
ともに値が3に更新されている。


上記のような問題がある為、JAVA言語やC#言語などは禁止(コンパイルエラー)されています。

一覧へ
 
    
A8ネット
 ・人気度:★★★★★
 ・言わずと知れた人気ASP

 
楽天市場
 ・人気度:★★★★★
 ・誰でも安心、楽天市場で

タワーレコード
 ・人気度:★★★★☆
 ・CD/DVDならタワレコで

 
■ネット証券関連おすすめ
イー・トレード証券
 ・人気度:★★★★★
 ・初心者はこちらから

マネックス証券
 ・人気度:★★★★★
 ・中級者ならこちらから






Copyright(C)2007 得@スキルアップ塾.comAll right reserved.