親メンバーへのアクセス
CoddyのCジャーニー「オブジェクト指向プログラミング」セクションの一部。レッスン 30/61。
struct の埋め込みと first member ルールを理解したので、ここでは実践的な側面に焦点を当てましょう。つまり、function 内から埋め込まれた parent のデータを読み取り、変更する方法です。
関数が Child 構造体(またはそのポインター)を受け取る場合、parent のメンバーにアクセスするには、埋め込み構造体をたどる必要があります。構文は、値を扱っているかポインターを扱っているかによって異なります。
typedef struct {
int id;
int score;
} Parent;
typedef struct {
Parent parent;
char grade;
} Child;ポインタで Child を指し、矢印演算子を使って parent に到達し、次にドットでそのメンバーにアクセスします:
void update_score(Child* c, int new_score) {
c->parent.score = new_score; // アローの後にドット
}
void print_info(Child* c) {
printf("ID: %d, Score: %d\n", c->parent.id, c->parent.score);
}値(コピー渡し)では、全体を通してドットを使用します:
void show_id(Child c) {
printf("ID: %d\n", c.parent.id); // ドット、そしてドット
}この連鎖アクセスパターン child->parent.member または child.parent.member は、C のコンポジションモデルで継承されたデータを操作する方法です。真の継承より少し冗長ですが、型間の関係が明示的で分かりやすくなります。
チャレンジ
簡単埋め込み構造体 inside のデータにアクセスして modify する方法を示す student grading system を作成しましょう。Student が埋め込み Person を含む hierarchy を作り、child を通して parent のデータを扱う function を記述します。
コードを3つのファイルに分けて整理します。
student.h: include guards を使用して struct hierarchy を Define します。name(50 characters の character array)とage(integer)を持つPersonstruct を Create します。次に、Personを first member として embedded し、gradefield(score を表す integer)を追加したStudentstruct を Define します。Student*と new age value を受け取るset_person_agefunction と、Student*を受け取って all information を displays するprint_studentfunction の2つを Declare します。student.c: 両方の function を Implement します。set_person_agefunction は、embeddedPersonstruct inside の age を modify する必要があります。ここで arrow-then-dot syntax(s->person.age)を練習します。print_studentfunction は、embedded person と student 自身の両方から all fields にアクセスして displays する必要があります。main.c:Studentvariable を Create し、その all fields を Initialize します。次にset_person_ageを使用して embedded person の age を update し、print_studentを Call して結果を displays します。
4つの inputs を受け取ります:student の name(string)、その initial age(integer)、grade(integer)、そして new age(function を通して update する integer)です。
main file で initial values を使用して student を Create し、次に set_person_age を Call して age を new value に変更し、最後に print_student を Call して updated information を displays します。
Output は次のようになります。
Name: Emma
Age: 21
Grade: 85ここで Emma は name、21 は updated age(initial age ではありません)、85 は grade です。ここでの重要な学習内容は、embedded struct を通して parent の members を read と write の両方で扱う方法です。
自分で試してみよう
#include <stdio.h>
#include <string.h>
#include "student.h"
int main() {
char name[50];
int initial_age, grade, new_age;
// 入力を読み取る
fgets(name, 50, stdin);
name[strcspn(name, "\n")] = '\0'; // 改行を削除
scanf("%d", &initial_age);
scanf("%d", &grade);
scanf("%d", &new_age);
// TODO: Student変数を作成する
// TODO: studentのすべてのフィールドを初期化する
// - strcpyを使用してnameを埋め込まれたpersonのnameにコピーする
// - 埋め込まれたpersonのageをinitial_ageに設定する
// - studentのgradeを設定する
// TODO: set_person_ageを呼び出してageをnew_ageに更新する
// TODO: print_studentを呼び出して結果を表示する
return 0;
}
このレッスンには短いクイズがあります。レッスンを始めて解答し、進捗を記録しましょう。
オブジェクト指向プログラミングのすべてのレッスン
自分で練習してみよう: Cオンラインコンパイラ