File tree Expand file tree Collapse file tree
public/docs/cpp/8-inheritance Expand file tree Collapse file tree Original file line number Diff line number Diff line change @@ -9,6 +9,12 @@ question:
99 にするとどうなりますか?
1010 - 親クラスのメンバ変数 `name` は、子クラスで自動的に使えるようになるのですか?
1111 - ' `Dog` クラスが `Animal` と `Canine` のように、複数のクラスから同時に継承することはできますか?'
12+ term :
13+ - 継承
14+ - 親クラス
15+ - 基底クラス
16+ - 子クラス
17+ - 派生クラス
1218---
1319
1420## クラスの継承
@@ -19,6 +25,8 @@ question:
1925
2026C++では、[[ クラス]] 名の後に ` : public 親クラス名 ` と書くことで継承を表現します。
2127
28+ 以下の例では、` Dog ` [[ クラス]] は` Animal ` [[ クラス]] を継承しています。そのため、` Dog ` [[ クラス]] の[[ オブジェクト]] ` my_dog ` は、` Animal ` [[ クラス]] で定義された[[ メンバ変数]] ` name ` や[[ メンバ関数]] ` eat() ` を、まるで自分のものであるかのように利用できます。
29+
2230``` cpp:inheritance_basic.cpp
2331#include < iostream>
2432#include < string>
@@ -60,5 +68,3 @@ int main() {
6068Pochi is eating.
6169Pochi says Woof!
6270```
63-
64- この例では、` Dog ` [[ クラス]] は` Animal ` [[ クラス]] を継承しています。そのため、` Dog ` [[ クラス]] の[[ オブジェクト]] ` my_dog ` は、` Animal ` [[ クラス]] で定義された[[ メンバ変数]] ` name ` や[[ メンバ関数]] ` eat() ` を、まるで自分のものであるかのように利用できます。
Original file line number Diff line number Diff line change @@ -7,15 +7,20 @@ question:
77 - ' `virtual` キーワードを付けないとどうなりますか?例の `make_animal_speak` 関数ではどういう結果になりますか?'
88 - なぜ `Animal*` のポインタや参照を使う必要があるのですか?直接オブジェクトを渡すのと何が違いますか?
99 - 親クラスのポインタが子クラスのオブジェクトを指せるのはなぜですか?
10+ term :
11+ - 仮想関数
12+ - ポリモーフィズム
13+ - 多態性
14+ - virtual
1015---
1116
1217## 仮想関数 (virtual) とポリモーフィズム
1318
14- 継承の最も強力な側面は 、** ポリモーフィズム(多態性)** を実現できることです。ポリモーフィズムとは、ギリシャ語で「多くの形を持つ」という意味で、プログラミングにおいては「** 同じインターフェース(指示)で、オブジェクトの種類に応じて異なる振る舞いをさせる** 」ことを指します。
19+ [[ 継承 ]] の最も強力な側面は 、** ポリモーフィズム(多態性)** を実現できることです。ポリモーフィズムとは、ギリシャ語で「多くの形を持つ」という意味で、プログラミングにおいては「** 同じインターフェース(指示)で、オブジェクトの種類に応じて異なる振る舞いをさせる** 」ことを指します。
1520
16- これを実現するのが ** 仮想関数 (virtual function)** です。親クラスの関数宣言の前に ` virtual ` キーワードを付けると、その関数は仮想関数になります。
21+ これを実現するのが ** 仮想関数 (virtual function)** です。[[ 親クラス ]] の関数宣言の前に ` virtual ` キーワードを付けると、その関数は仮想関数になります。
1722
18- 親クラスの [[ ポインタ]] や参照は、子クラスの [[ オブジェクト]] を指すことができます。このとき、呼び出された仮想関数は、[[ ポインタ]] が指している** [[ オブジェクト]] の実際の型** に基づいて決定されます。
23+ [[ 親クラス ]] の [[ ポインタ]] や参照は、[[ 子クラス ]] の [[ オブジェクト]] を指すことができます。このとき、呼び出された仮想関数は、[[ ポインタ]] が指している** [[ オブジェクト]] の実際の型** に基づいて決定されます。
1924
2025言葉だけでは難しいので、コードで見てみましょう。
2126
Original file line number Diff line number Diff line change @@ -6,13 +6,16 @@ question:
66 - ' `override` を付けなくても、子クラスで親クラスと同じ名前の関数を定義すれば、それが呼ばれるのではないのですか?'
77 - ' `override` を付けることで具体的にどのようなバグが防げるのですか?'
88 - ' `final` というキーワードも見たことがあります。`override` と `final` はどう違うのですか?'
9+ term :
10+ - オーバーライド
11+ - override
912---
1013
1114## オーバーライド (override)
1215
13- 先ほどの例で ` override ` というキーワードが登場しましたね。これはC++11から導入されたもので、子クラスの関数が ** 親クラスの仮想関数を上書き (オーバーライド)する意図があることを明示する** ためのものです。
16+ 先ほどの例で ` override ` というキーワードが登場しましたね。これはC++11から導入されたもので、[[ 子クラス ]] の関数が ** [[ 親クラス ]] の [[ 仮想関数 ]] を上書き (オーバーライド)する意図があることを明示する** ためのものです。
1417
15- ` override ` を付けておくと、もし親クラスに対応する仮想関数が存在しない場合 (例えば、関数名をタイプミスした場合など)に、コンパイラがエラーを検出してくれます。
18+ ` override ` を付けておくと、もし [[ 親クラス ]] に対応する [[ 仮想関数 ]] が存在しない場合 (例えば、関数名をタイプミスした場合など)に、コンパイラがエラーを検出してくれます。
1619
1720``` cpp
1821class Dog : public Animal {
@@ -25,4 +28,4 @@ public:
2528};
2629```
2730
28- 意図しないバグを防ぐために、仮想関数をオーバーライドする際は必ず `override` を付ける習慣をつけましょう。
31+ 意図しないバグを防ぐために、[[仮想関数]]をオーバーライドする際は必ず `override` を付ける習慣をつけましょう。
Original file line number Diff line number Diff line change @@ -8,11 +8,14 @@ question:
88 - 抽象クラスを使うと、どんな良いことがありますか?
99 - ' `virtual ~Shape() {}` のように、デストラクタに `virtual` を付けるのはなぜですか?'
1010 - もし子クラスが純粋仮想関数を実装しなかったらどうなりますか?
11+ term :
12+ - 抽象クラス
13+ - 純粋仮想関数
1114---
1215
1316## 抽象クラス
1417
15- 時には、「具体的な実装を持たず、子クラスに実装を強制するための設計図 」としてのみ機能する[[ クラス]] を定義したい場合があります。これが** 抽象クラス (Abstract Class)** です。
18+ 時には、「具体的な実装を持たず、[[ 子クラス ]] に実装を強制するための設計図 」としてのみ機能する[[ クラス]] を定義したい場合があります。これが** 抽象クラス (Abstract Class)** です。
1619
1720抽象クラスは、** 純粋仮想関数 (pure virtual function)** を1つ以上持つ[[ クラス]] です。純粋仮想関数は、末尾に ` = 0 ` を付けて宣言します。
1821
@@ -23,7 +26,7 @@ virtual void function_name() = 0; // これが純粋仮想関数
2326抽象クラスは以下の特徴を持ちます。
2427
2528 * [[ インスタンス化]] ([[ オブジェクト]] の作成)ができない。
26- * 抽象クラスを継承した子クラスは、全ての純粋仮想関数をオーバーライド (実装)しなければならない。さもなければ、その子クラスもまた抽象クラスとなる 。
29+ * 抽象クラスを [[ 継承 ]] した [[ 子クラス ]] は、全ての純粋仮想関数を [[ オーバーライド ]] (実装)しなければならない。さもなければ、その [[ 子クラス ]] もまた抽象クラスとなる 。
2730
2831``` cpp:abstract_class_example.cpp
2932#include < iostream>
@@ -74,4 +77,4 @@ Drawing a circle: ○
7477Drawing a square: □
7578```
7679
77- ` Shape ` [[ クラス]] は「図形なら描画できるはずだ」というインターフェース(契約)を定義し、具体的な描画方法は子クラスである ` Circle ` や ` Square ` に任せています。このように、抽象クラスはプログラムの骨格となる設計を強制するのに非常に役立ちます。
80+ ` Shape ` [[ クラス]] は「図形なら描画できるはずだ」というインターフェース(契約)を定義し、具体的な描画方法は [[ 子クラス ]] である ` Circle ` や ` Square ` に任せています。このように、抽象クラスはプログラムの骨格となる設計を強制するのに非常に役立ちます。
Original file line number Diff line number Diff line change @@ -7,8 +7,8 @@ question: []
77
88## この章のまとめ
99
10- * ** 継承 ** : 既存の[[ クラス]] の機能を引き継ぎ、コードの再利用性を高める仕組みです。` (子クラス) : public (親クラス) ` のように書きます。
11- * ** ポリモーフィズム** : 「同じ指示でも、オブジェクトの種類によって異なる振る舞いをさせる」性質です。
12- * ** 仮想関数 (` virtual ` )** : ポリモーフィズムを実現するための鍵です。親クラスの関数に ` virtual ` を付けると、[[ ポインタ]] や参照経由で呼び出した際に、[[ オブジェクト]] の実際の型に応じた関数が実行されます。
13- * ** オーバーライド (` override ` )** : 子クラスで親クラスの仮想関数を上書きする意図を明示します 。コンパイラがチェックしてくれるため、安全性が向上します。
14- * ** 抽象クラス** : 1つ以上の** 純粋仮想関数 (` virtual ... = 0; ` )** を持つ[[ クラス]] です。[[ インスタンス化]] できず、継承されるための設計図として機能します 。
10+ * ** [[ 継承 ]] ** : 既存の[[ クラス]] の機能を引き継ぎ、コードの再利用性を高める仕組みです。` (子クラス) : public (親クラス) ` のように書きます。
11+ * ** [[ ポリモーフィズム]] ** : 「同じ指示でも、オブジェクトの種類によって異なる振る舞いをさせる」性質です。
12+ * ** [[ 仮想関数]] (` virtual ` )** : ポリモーフィズムを実現するための鍵です。[[ 親クラス ]] の関数に ` virtual ` を付けると、[[ ポインタ]] や参照経由で呼び出した際に、[[ オブジェクト]] の実際の型に応じた関数が実行されます。
13+ * ** [[ オーバーライド]] (` override ` )** : [[ 子クラス ]] で [[ 親クラス ]] の [[ 仮想関数 ]] を上書きする意図を明示します 。コンパイラがチェックしてくれるため、安全性が向上します。
14+ * ** [[ 抽象クラス]] ** : 1つ以上の** [[ 純粋仮想関数]] (` virtual ... = 0; ` )** を持つ[[ クラス]] です。[[ インスタンス化]] できず、[[ 継承 ]] されるための設計図として機能します 。
Original file line number Diff line number Diff line change @@ -9,7 +9,7 @@ question:
99
1010### 練習問題1:乗り物の階層構造
1111
12- ` Vehicle ` という親クラスを作成し、` move() ` という[[ メンバ関数]] を持たせましょう。次に、` Vehicle ` を継承して ` Car ` [[ クラス]] と ` Motorcycle ` [[ クラス]] を作成し、それぞれが独自の ` move() ` の振る舞いをするようにオーバーライドしてください 。
12+ ` Vehicle ` という親クラスを作成し、` move() ` という[[ メンバ関数]] を持たせましょう。次に、` Vehicle ` を継承して ` Car ` [[ クラス]] と ` Motorcycle ` [[ クラス]] を作成し、それぞれが独自の ` move() ` の振る舞いをするように [[ オーバーライド ]] してください 。
1313
1414[[ ` main ` 関数]] では、` Vehicle ` の[[ ポインタ]] の配列を作成し、` Car ` と ` Motorcycle ` の[[ オブジェクト]] を格納して、ループでそれぞれの ` move() ` を呼び出してください。
1515
Original file line number Diff line number Diff line change @@ -12,7 +12,7 @@ question:
1212
1313### 問題2: 従業員の給与計算
1414
15- ` Employee ` という抽象クラスを定義してください 。このクラスは、従業員の名前を保持し、給与を計算するための純粋仮想関数 ` calculate_salary() ` を持ちます。
15+ ` Employee ` という [[ 抽象クラス ]] を定義してください 。このクラスは、従業員の名前を保持し、給与を計算するための [[ 純粋仮想関数 ]] ` calculate_salary() ` を持ちます。
1616
1717次に、` Employee ` を継承して、` FullTimeEmployee ` (月給制)と ` PartTimeEmployee ` (時給制)の2つの[[ クラス]] を作成します。それぞれのクラスで ` calculate_salary() ` を具体的に実装してください。
1818
You can’t perform that action at this time.
0 commit comments