C++継承モデル:多重・多段・階層継承の実践ガイド
C++継承モデル:多重、多段、階層継承
このチュートリアルでは、C++の継承パターンである多重継承、多段継承、階層継承を実践的なコード例で探ります。
継承はオブジェクト指向プログラミングの基盤機能です。既存クラスからプロパティと振る舞いを継承する新しいクラスを作成できます。
以下でC++で利用可能な3つの主要な継承モデルを検討します。
C++多段継承
多段階層では、あるクラスが別の派生クラスから派生します。この連鎖は基底クラスに達するまで続きます。
class A { // 基底クラス実装 };
class B : public A { // BはAから継承 };
class C : public B { // CはBから継承 };
ここで、BはAから継承し、CはBから継承し、垂直な継承チェーンを形成します。
例1: C++多段継承
#include <iostream>
using namespace std;
class A {
public:
void display() {
cout << "Base class content." << endl;
}
};
class B : public A {};
class C : public B {};
int main() {
C obj;
obj.display();
return 0;
}
出力
Base class content.
このプログラムは、BやCにオーバーライド実装が存在しないため、Cのオブジェクトが究極の基底クラスAで定義されたdisplay()を呼び出せることを示しています。コンパイラは最も派生したクラスから上向きに継承チェーンを探索して呼び出しを解決します。
C++多重継承
C++では、1つのクラスが複数の基底クラスから継承できます。例えば、Bat(コウモリ)はMammal(哺乳類)とWingedAnimal(翼を持つ動物)の両方から派生できます。コウモリは同時に哺乳類であり翼を持つ生物だからです。
例2: C++多重継承
#include <iostream>
using namespace std;
class Mammal {
public:
Mammal() {
cout << "Mammals can give direct birth." << endl;
}
};
class WingedAnimal {
public:
WingedAnimal() {
cout << "Winged animals can flap." << endl;
}
};
class Bat : public Mammal, public WingedAnimal {};
int main() {
Bat b1;
return 0;
}
出力
Mammals can give direct birth. Winged animals can flap.
多重継承における曖昧性の解決
2つの基底クラスが同じ名前の関数を提供している場合、コンパイラはどちらを呼び出すか判断できず、曖昧性エラーになります。
class Base1 {
public:
void someFunction() { /* ... */ }
};
class Base2 {
public:
void someFunction() { /* ... */ }
};
class Derived : public Base1, public Base2 {};
int main() {
Derived obj;
// obj.someFunction(); // エラー: ambiguous
}
スコープ解決演算子を使って、呼び出したい基底クラスの関数を指定します:
int main() {
Derived obj;
obj.Base1::someFunction(); // Base1の実装を呼び出し
obj.Base2::someFunction(); // Base2の実装を呼び出し
}
C++階層継承
階層継承では、複数の派生クラスが1つの基底クラスから継承します。共通の属性と振る舞いを基底クラスにカプセル化し、各派生クラスが独自の特化を追加できます。
例として、Physics(物理)、Chemistry(化学)、Biology(生物)がScience(科学)から派生する場合や、Dog、Cat、HorseがAnimalから派生する場合があります。
階層継承の構文
class BaseClass { // 基底クラスの内容 };
class DerivedOne : public BaseClass { // 追加メンバ };
class DerivedTwo : public BaseClass { // 追加メンバ };
class DerivedThree : public BaseClass { // 追加メンバ };
例3: C++階層継承
// 階層継承を示すC++プログラム
#include <iostream>
using namespace std;
// 基底クラス
class Animal {
public:
void info() {
cout << "I am an animal." << endl;
}
};
// 派生クラス1
class Dog : public Animal {
public:
void bark() {
cout << "I am a Dog. Woof woof." << endl;
}
};
// 派生クラス2
class Cat : public Animal {
public:
void meow() {
cout << "I am a Cat. Meow." << endl;
}
};
int main() {
// Dogインスタンス
Dog dog1;
cout << "Dog Class:" << endl;
dog1.info();
dog1.bark();
// Catインスタンス
Cat cat1;
cout << "\nCat Class:" << endl;
cat1.info();
cat1.meow();
return 0;
}
出力
Dog Class: I am an animal. I am a Dog. Woof woof. Cat Class: I am an animal. I am a Cat. Meow.
DogとCatの両方がAnimalからinfo()メソッドを継承し、それぞれ独自の特化した振る舞いを導入しています。
C言語
- C# クラスとオブジェクト:堅牢な OOP の基礎
- C# 抽象クラスと抽象メソッドをマスターする:実践ガイド
- C# 部分クラスと部分メソッドを理解する
- C# sealed クラスとメソッドをマスターする:使用判断、実例、コードの安全性とパフォーマンス向上
- C++クラスとオブジェクト完全ガイド:オブジェクト指向プログラミングの実践
- C++ public/protected/private継承の違いを徹底解説
- C++フレンド関数とフレンドクラス:アクセス制御のマスター
- C++ structとclassの違い:構文、特徴、使い分けのベストプラクティス
- C++ストレージクラス完全解説:スコープ、ライフタイム、使い方
- C++日付と時刻の完全ガイド:ctimeライブラリの活用
- C++ポリモーフィズム完全理解:仮想関数と純粋仮想関数