Menu
Coddy logo textTech

構造体の埋め込み

CoddyのCジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 28/61。

C++やJavaのようなオブジェクト指向言語では、継承によってクラスはparentクラスからプロパティを取得できます。Cには組み込みの継承はありませんが、1つのstructを別のstructの中に配置する、コンポジションと呼ばれる手法を使ってこれをシミュレートできます。

考え方は単純です。ChildParent のすべてのプロパティを必要とする場合、Parent 構造体を Child のメンバーとして埋め込みます。

typedef struct {
    int id;
    char name[50];
} Parent;

typedef struct {
    Parent parent;  // 埋め込み構造体
    int grade;
} Child;

ここでは、ChildにはParentが持つすべてのものに加えて、独自のgradeフィールドが含まれています。これはコンポジションです。子は親「である」のではなく、親「を持つ」ことになりますが、その効果は継承と似ています。

子インスタンスを通じて親のメンバーにアクセスするには、ドット演算子を2回使用します:

Child c;
c.parent.id = 101;
c.parent.name[0] = 'A';
c.grade = 5;

このパターンは、Cで型階層を構築するための基盤となります。base struct をfirst memberとして埋め込むことで、今後のレッスンで詳しく学ぶ強力なテクニックを活用できるようになります。

challenge icon

チャレンジ

簡単

Cにおける継承の基礎である構造体の埋め込みを示す、シンプルな employee 管理システムを作成しましょう。

EmployeePerson を含む階層構造を作成します。これは継承の仕組みを反映しています。つまり、employee "is a" person であり、さらに職務に関する information を持つということです。Person 構造体を Employee の内部に埋め込むことで、person のすべてのプロパティに加えて、employee 固有のフィールドも利用できます。

コードを3つのファイルに整理します。

  • types.h:ここで include ガードとともに両方の構造体を Define します。まず、2つのフィールドを持つ Person 構造体を作成します。フィールドは name(50 characters の character array)と age(integer)です。次に、Person を first member として埋め込み、employee_id フィールド(integer)を追加した Employee 構造体を define します。
  • types.cEmployee への pointer を受け取り、その information を表示する print_employee という Function を Implement します。学習した chained dot/arrow 構文を使用して、埋め込まれた person の data に access します。
  • main.cEmployee variable を作成し、埋め込まれた person の name と age を含むすべてのフィールドを Populate して、print Function を使用して information を表示します。

3つの入力を受け取ります。employee の name(string)、age(integer)、および employee ID(integer)です。

print_employee Function は、employee の information を次の形式で出力します。

Employee: Alice
Age: 28
ID: 1001

ここで、Alice は name、28 は age、1001 は入力された employee ID です。

埋め込まれた構造体の member には parent member を通して access することを忘れないでください。たとえば、name に到達するには、まず person member を経由します。

自分で試してみよう

#include <stdio.h>
#include <string.h>
#include "types.h"

int main() {
    // 入力を読み取る
    char name[50];
    int age;
    int employee_id;
    
    fgets(name, 50, stdin);
    name[strcspn(name, "\n")] = '\0';  // 改行を削除
    scanf("%d", &age);
    scanf("%d", &employee_id);
    
    // TODO: Employee変数を作成する
    
    // TODO: 埋め込まれたpersonのnameとageを設定する
    // Hint: 名前にはstrcpyを使い、employee.person.nameでアクセスする
    
    // TODO: employee_idを設定する
    
    // TODO: employeeへのポインタでprint_employeeを呼び出す
    
    return 0;
}
quiz icon腕試し

このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。

オブジェクト指向プログラミングのすべてのレッスン

自分で練習してみよう: Cオンラインコンパイラ