Post

๐Ÿข chap8. ์ƒ์†๊ณผ ๋‹คํ˜•์„ฑ

โญ 8.1 ์ƒ์†

์ƒ์† ๊ด€๊ณ„: to-be ๊ด€๊ณ„, ํ™•์žฅ ๊ด€๊ณ„extention relationship

์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ๋‹ค๋ฅธ ๊ฐ์ฒด์™€ ๊ฐ™์€ ์†์„ฑ์„ ๊ฐ–๊ณ  ์žˆ๋Š”๋ฐ ๋‹ค๋ฅธ ์ถ”๊ฐ€ ์†์„ฑ์„ ๊ฐ€์ง„ ๊ฒฝ์šฐ

์˜ˆ) ํ•™์ƒ์€ ์‚ฌ๋žŒ์ด๋ผ๋Š” ๋ชจ๋“  ์†์„ฑ์„ ๊ฐ–๊ณ  ์žˆ์œผ๋‚˜ ๋‹ค๋ฅธ ์ถ”๊ฐ€ ์†์„ฑ์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Œ

  • ์ฝ”๋“œ ๋ฐ•์Šค 8-1 (p.316)

Person ํด๋ž˜์Šค์™€ Student ํด๋ž˜์Šค ์†์„ฑ ๊ตฌ์กฐ์ฒด

โ†’ ์ƒˆ๋กœ์šด ์†์„ฑ์œผ๋กœ ํ™•์žฅ, to be ๊ด€๊ณ„, โ€˜ํ•™์ƒ์€ ์‚ฌ๋žŒ์ด๋‹คโ€™

person_t: ์Šˆํผํƒ€์ž…supertype, ๋ฒ ์ด์Šคํƒ€์ž…base type, ๋ถ€๋ชจ ํƒ€์ž…parent type

student_t: ์ž์‹ ํƒ€์ž…child type, ์ƒ์†๋ฐ›์€ ์„œ๋ธŒํƒ€์ž…inherited subtype

โ˜‘๏ธ ์ƒ์†์˜ ๋ณธ์งˆ

์ƒ์† ๊ด€๊ณ„: ์ผ๋Œ€์ผ ํ•ฉ์„ฑ ๊ด€๊ณ„

Student ํด๋ž˜์Šค์˜ ์†์„ฑ ๊ตฌ์กฐ์ฒด ๋‚ด๋ถ€์— ๋น„๊ณต๊ฐœ person ๊ฐ์ฒด๊ฐ€ ์กด์žฌ

โ†’ํ•™์ƒ ๋‚ด๋ถ€์— ์ธ๊ฐ„์˜ ์†์„ฑ์„ ๊ฐ€์ง

  • ์ฝ”๋“œ ๋ฐ•์Šค 8-2 (p.317)

Person ํด๋ž˜์Šค์™€ Student ํด๋ž˜์Šค ์†์„ฑ ๊ตฌ์กฐ์ฒด(์ค‘์ฒฉ๋จ)

โ†’ ํฌ์ธํ„ฐ๊ฐ€ ์•„๋‹Œ ๊ตฌ์กฐ์ฒด ๋ณ€์ˆ˜ ์‚ฌ์šฉ, ์ด์ „ ๊ตฌ์กฐ์ฒด๋ฅผ ์ƒ์†ํ•œ ์ƒˆ ๊ตฌ์กฐ์ฒด ๋‚ด๋ถ€์— ๊ตฌ์กฐ์ฒด ๋ณ€์ˆ˜๋ฅผ ๊ฐ€์ง

์—…์บ์ŠคํŒ…: ์ž์‹์˜ ์†์„ฑ ๊ตฌ์กฐ์ฒด ์ž๋ฃŒํ˜•์˜ ํฌ์ธํ„ฐ๋ฅผ ๋ถ€๋ชจ ์†์„ฑ ๊ตฌ์กฐ์ฒด ์ž๋ฃŒํ˜•์œผ๋กœ ๋ณ€ํ™˜

student_t ํฌ์ธํ„ฐ๋ฅผ person_t ํฌ์ธํ„ฐ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Œ

  • ์˜ˆ์ œ 8-1 (p.318)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    
    #include <stdio.h>
    
    typedef struct {
      char first_name[32];
      char last_name[32];
      unsigned int birth_year;
    } person_t;
    
    typedef struct {
      person_t person;
      char student_number[16]; // ์ถ”๊ฐ€ ์†์„ฑ
      unsigned int passed_credits; // ์ถ”๊ฐ€ ์†์„ฑ
    } student_t;
    
    int main(int argc, char** argv) {
      student_t s;
      student_t* s_ptr = &s;
      person_t* p_ptr = (person_t*)&s;
      printf("Student pointer points to %p\n", (void*)s_ptr);
      printf("Person pointer points to %p\n", (void*)p_ptr);
      return 0;
    }
    

    s_ptr๊ณผ p_ptr ํฌ์ธํ„ฐ๋Š” ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๊ฐ™์€ ์ฃผ์†Œ๋ฅผ ๊ฐ€๋ฆฌํ‚ด

    1
    2
    3
    4
    
    gcc ExtremeC_examples_chapter8_1.c -o ex8_1.out
    ./ex8_1.out
    //Student pointer points to 0x7ffeb64e6500
    //Person pointer points to 0x7ffeb64e6500
    

    student_tํ˜•์˜ ๊ตฌ์กฐ์ฒด ๋ณ€์ˆ˜๊ฐ€ person_t ๊ตฌ์กฐ์ฒด๋ฅผ ์ƒ์†ํ•œ๋‹ค๋Š” ๋œป

    โ†’ student ๊ฐ์ฒด๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ๋กœ Person ํด๋ž˜์Šค์˜ ํ–‰์œ„ ํ•จ์ˆ˜ ์‚ฌ์šฉ ๊ฐ€๋Šฅ

  • ์ฝ”๋“œ ๋ฐ•์Šค 8-3 (p.319)

์ปดํŒŒ์ผ๋˜์ง€ ์•Š๋Š” ์ƒ์† ๊ด€๊ณ„ ๋งŒ๋“ค๊ธฐ

๋ถˆ์™„์ „ํ•œ ํ˜•์‹ ์„ ์–ธโ†’๋ณ€์ˆ˜ ์ƒ์„ฑ ๋ถˆ๊ฐ€๋Šฅ, ํž™ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น ๋ถˆ๊ฐ€๋Šฅ

์ค‘์ฒฉ๋œ ๊ตฌ์กฐ์ฒด ๋ณ€์ˆ˜ ์‚ฌ์šฉ์„ ์œ„ํ•ด์„œ๋Š” student_t ๊ตฌ์กฐ์ฒด๊ฐ€ ๋น„๊ณต๊ฐœ์ธ person_t ๊ตฌ์กฐ์ฒด์˜ ์‹ค์ œ ์ •์˜๋ฅผ ์•Œ์•„์•ผ ํ•จ

์ƒ์† ๊ด€๊ณ„ ๊ตฌํ˜„์„ ์œ„ํ•œ ์ ‘๊ทผ ๋ฐฉ๋ฒ•

  1. ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ๋ฒ ์ด์Šค ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๋น„๊ณต๊ฐœ ๊ตฌํ˜„์— ์ ‘๊ทผ
  2. ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ๋ฒ ์ด์Šค ํด๋ž˜์Šค์˜ ๊ณต์šฉ ์ธํ„ฐํŽ˜์ด์Šค์—๋งŒ ์ ‘๊ทผ

โ˜‘๏ธ C์˜ ์ƒ์†์— ๊ด€ํ•œ ์ฒซ ๋ฒˆ์งธ ์ ‘๊ทผ๋ฒ•

์ฒซ ๋ฒˆ์งธ ์ ‘๊ทผ๋ฒ•์— ๋Œ€ํ•ด ์˜ˆ์ œ 8-2์—์„œ ์„ค๋ช…

Student ํด๋ž˜์Šค๋Š” Person ํด๋ž˜์Šค์˜ ์†์„ฑ ๊ตฌ์กฐ์ฒด์— ๋Œ€ํ•œ ์‹ค์ œ ๋น„๊ณต๊ฐœ ์ •์˜์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•จ

  • ์˜ˆ์ œ 8-2

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    
    #ifndef EXTREME_C_EXAMPLES_CHAPTER_8_2_PERSON_H
    #define EXTREME_C_EXAMPLES_CHAPTER_8_2_PERSON_H
    
    // ์ „๋ฐฉ ์„ ์–ธ
    struct person_t;
    
    // ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ž
    struct person_t* person_new();
    
    // ์ƒ์„ฑ์ž
    void person_ctor(struct person_t*,
                     const char*  /* first name */,
                     const char*  /* last name */,
                     unsigned int /* birth year */);
    
    // ์†Œ๋ฉธ์ž
    void person_dtor(struct person_t*);
    
    // ํ–‰์œ„ ํ•จ์ˆ˜
    void person_get_first_name(struct person_t*, char*);
    void person_get_last_name(struct person_t*, char*);
    unsigned int person_get_birth_year(struct person_t*);
    
    #endif
    

    Person ํด๋ž˜์Šค๋ฅผ ์„ ์–ธํ•˜๋Š” ํ—ค๋” ํŒŒ์ผ ์ƒ์„ฑ์ž ํ•จ์ˆ˜โ†’person ๊ฐ์ฒด ์ƒ์„ฑ์„ ์œ„ํ•œ ๋ชจ๋“  ๊ฐ’์„ ๋ฐ›์Œ ์†์„ฑ ๊ตฌ์กฐ์ฒด person_t์— ๋Œ€ํ•œ ์‹ค์ œ ์ •์˜๋ฅผ ํฌํ•จํ•˜๋ฉด ์•ˆ๋จ(์บก์Šํ™”)โ†’๋น„๊ณต๊ฐœ ํ—ค๋” ํŒŒ์ผ(์ด ํ—ค๋”์˜ ์‹ค์ œ ์ •์˜๋ฅผ ํฌํ•จํ•˜๋Š” ํ—ค๋” ํŒŒ์ผ)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    
    #ifndef EXTREME_C_EXAMPLES_CHAPTER_8_2_PERSON_P_H
    #define EXTREME_C_EXAMPLES_CHAPTER_8_2_PERSON_P_H
    
    // ๋น„๊ณต๊ฐœ ์ •์˜
    typedef struct {
      char first_name[32];
      char last_name[32];
      unsigned int birth_year;
    } person_t;
    
    #endif
    

    ์ด๋Š” Person ํด๋ž˜์Šค์˜ ์ผ๋ถ€๋ถ„, student_t ์†์„ฑ ๊ตฌ์กฐ์ฒด๋ฅผ ์ •์˜ํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    
    #include <stdlib.h>
    #include <string.h>
    
    // person_t๋Š” ๋‹ค์Œ ํ—ค๋” ํŒŒ์ผ์— ์ •์˜๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.
    #include "ExtremeC_examples_chapter8_2_person_p.h"
    
    // ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ž
    person_t* person_new() {
      return (person_t*)malloc(sizeof(person_t));
    }
    
    // ์ƒ์„ฑ์ž
    void person_ctor(person_t* person,
                     const char* first_name,
                     const char* last_name,
                     unsigned int birth_year) {
      strcpy(person->first_name, first_name);
      strcpy(person->last_name, last_name);
      person->birth_year = birth_year;
    }
    
    // ์†Œ๋ฉธ์ž
    void person_dtor(person_t* person) {
      // ํ•  ์ผ ์—†์Œ
    }
    
    // ํ–‰์œ„ ํ•จ์ˆ˜
    void person_get_first_name(person_t* person, char* buffer) {
      strcpy(buffer, person->first_name);
    }
    
    void person_get_last_name(person_t* person, char* buffer) {
      strcpy(buffer, person->last_name);
    }
    
    unsigned int person_get_birth_year(person_t* person) {
      return person->birth_year;
    }
    

    Person ํด๋ž˜์Šค์˜ ๋น„๊ณต๊ฐœ ๊ตฌํ˜„์„ ๋‚˜ํƒ€๋ƒ„

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    #ifndef EXTREME_C_EXAMPLES_CHAPTER_8_2_STUDENT_H
    #define EXTREME_C_EXAMPLES_CHAPTER_8_2_STUDENT_H
    
    // ์ „๋ฐฉ ์„ ์–ธ
    struct student_t;
    
    // ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ž
    struct student_t* student_new();
    
    // ์ƒ์„ฑ์ž
    void student_ctor(struct student_t*,
                      const char*  /* first name */,
                      const char*  /* last name */,
                      unsigned int /* birth year */,
                      const char*  /* student number */,
                      unsigned int /* passed credits */);
    
    // ์†Œ๋ฉธ์ž
    void student_dtor(struct student_t*);
    
    // ํ–‰์œ„ ํ•จ์ˆ˜
    void student_get_student_number(struct student_t*, char*);
    unsigned int student_get_passed_credits(struct student_t*);
    
    #endif
    

    Student ํด๋ž˜์Šค์˜ ๊ณต์šฉ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๋‚˜ํƒ€๋ƒ„ student ๊ฐ์ฒด๊ฐ€ ์‹ค์ œ๋กœ person ๊ฐ์ฒด๋ฅผ ํฌํ•จโ†’Person ํด๋ž˜์Šค์˜ ์ƒ์„ฑ์ž์™€ ๋น„์Šทํ•œ ์ธ์ž๋ฅผ ๋ฐ›์Œ ํ–‰์œ„ ํ•จ์ˆ˜๊ฐ€ 2๊ฐœ๋ฟ: Person ํด๋ž˜์Šค์˜ ํ–‰์œ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    
    #include <stdlib.h>
    #include <string.h>
    
    #include "ExtremeC_examples_chapter8_2_person.h"
    
    // 1. person_t๋Š” ๋‹ค์Œ ํ—ค๋” ํŒŒ์ผ์— ์ •์˜๋˜์–ด ์žˆ์œผ๋ฉฐ ์—ฌ๊ธฐ์—์„œ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.
    #include "ExtremeC_examples_chapter8_2_person_p.h"
    
    // ์ „๋ฐฉ ์„ ์–ธ
    typedef struct {
      // 2. ์—ฌ๊ธฐ์—์„œ person ํด๋ž˜์Šค์—์„œ ๋ชจ๋“  ์†์„ฑ์„ ์ƒ์†๋ฐ›์œผ๋ฉฐ,
      // ์ด ์ค‘์ฒฉ์œผ๋กœ ์ธํ•ด person ํด๋ž˜์Šค์˜ ๋ชจ๋“  ํ–‰์œ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
      person_t person;
      char* student_number;
      unsigned int passed_credits;
    } student_t;
    
    // ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ž
    student_t* student_new() {
      return (student_t*)malloc(sizeof(student_t));
    }
    
    // ์ƒ์„ฑ์ž
    void student_ctor(student_t* student,
                      const char* first_name,
                      const char* last_name,
                      unsigned int birth_year,
                      const char* student_number,
                      unsigned int passed_credits) {
      // 3. ๋ถ€๋ชจ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์ƒ์„ฑ์ž ํ˜ธ์ถœํ•˜๊ธฐ
      person_ctor((struct person_t*)student,
              first_name, last_name, birth_year);
      student->student_number = (char*)malloc(16 * sizeof(char));
      strcpy(student->student_number, student_number);
      student->passed_credits = passed_credits;
    }
    
    // ์†Œ๋ฉธ์ž
    void student_dtor(student_t* student) {
      // 4. ์ž์‹ ๊ฐ์ฒด๋ฅผ ๋จผ์ € ์†Œ๋ฉธ์‹œ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      free(student->student_number);
      // ๊ทธ๋Ÿฐ ๋‹ค์Œ, ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ์†Œ๋ฉธ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      person_dtor((struct person_t*)student);
    }
    
    // ํ–‰์œ„ ํ•จ์ˆ˜
    void student_get_student_number(student_t* student,
                                    char* buffer) {
      strcpy(buffer, student->student_number);
    }
    
    unsigned int student_get_passed_credits(student_t* student) {
      return student->passed_credits;
    }
    
    1. Person ํด๋ž˜์Šค์˜ ๋น„๊ณต๊ฐœ ํ—ค๋”๋ฅผ ํฌํ•จ
    2. person_t๊ฐ€ ์ด๋ฏธ ์ •์˜๋˜์–ด ์žˆ์–ด์•ผ ํ•จ
    3. ๋ถ€๋ชจ์˜ ์ƒ์„ฑ์ž ํ˜ธ์ถœโ†’๋ถ€๋ชจ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์†์„ฑ์„ ์ดˆ๊ธฐํ™”
    4. ์ž์‹ ์ˆ˜์ค€ ๋‹ค์Œ ๋ถ€๋ชจ ์ˆ˜์ค€์—์„œ ์†Œ๋ฉธ์ž๋ฅผ ํ˜ธ์ถœ
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "ExtremeC_examples_chapter8_2_person.h"
    #include "ExtremeC_examples_chapter8_2_student.h"
    
    int main(int argc, char** argv) {
      // student ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ์ƒ์„ฑํ•˜๊ธฐ
      struct student_t* student = student_new();
      student_ctor(student, "John", "Doe",
              1987, "TA5667", 134);
    
      // ์ด์ œ person์˜ ์†์„ฑ์„ student ๊ฐ์ฒด์—์„œ ์ฝ๊ธฐ ์œ„ํ•ด person์˜ ํ–‰์œ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
      char buffer[32];
    
      // ๋ถ€๋ชจ์˜ ์ž๋ฃŒํ˜•์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋กœ ์—…์บ์ŠคํŒ…ํ•˜๊ธฐ
      struct person_t* person_ptr = (struct person_t*)student;
    
      person_get_first_name(person_ptr, buffer);
      printf("First name: %s\n", buffer);
    
      person_get_last_name(person_ptr, buffer);
      printf("Last name: %s\n", buffer);
    
      printf("Birth year: %d\n", person_get_birth_year(person_ptr));
    
      // ์ด์ œ student ๊ฐ์ฒด์— ํ•œ์ •๋œ ์†์„ฑ์„ ์ฝ์Šต๋‹ˆ๋‹ค.
      student_get_student_number(student, buffer);
      printf("Student number: %s\n", buffer);
    
      printf("Passed credits: %d\n",
              student_get_passed_credits(student));
    
      // student ๊ฐ์ฒด๋ฅผ ์†Œ๋ฉธ ๋ฐ ํ•ด์ œํ•˜๊ธฐ
      student_dtor(student);
      free(student);
    
      return 0;
    }
    

    Person๊ณผ Student ํด๋ž˜์Šค ๋ชจ๋‘์— ๋Œ€ํ•œ ๊ณต์šฉ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํฌํ•จ, but ๊ฐ์ฒด๋Š” student๋งŒ ์ƒ์„ฑ student๋Š” person ๊ฐ์ฒด์—์„œ ๋ชจ๋“  ์†์„ฑ์„ ์ƒ์† ๋ฐ›์Œโ†’Person ํด๋ž˜์Šค์˜ ํ–‰์œ„ ํ•จ์ˆ˜๋กœ ์ฝ์„ ์ˆ˜ ์žˆ์Œ

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    gcc -c ExtremeC_examples_chapter8_2_person.c -o person.o
    gcc -c ExtremeC_examples_chapter8_2_student.c -o student.o
    gcc -c ExtremeC_examples_chapter8_2_main.c -o main.o
    gcc person.o student.o main.o -o ex8_2.out
    ./ex8_2.out
    //First name: John
    //Last name: Doe
    //Birth year: 1987
    //Student number: TA5667
    //Passed credits: 134
    

โ˜‘๏ธ C์˜ ์ƒ์†์— ๊ด€ํ•œ ๋‘ ๋ฒˆ์งธ ์ ‘๊ทผ๋ฒ•

๋‘ ๋ฒˆ์งธ ์ ‘๊ทผ๋ฒ•์— ๋Œ€ํ•ด ์˜ˆ์ œ 8-3์—์„œ ์„ค๋ช…

๋ถ€๋ชจ์˜ ๊ตฌ์กฐ์ฒด ๋ณ€์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ ์ƒ์„ฑโ†’์ž์‹ ํด๋ž˜์Šค๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค ๊ตฌํ˜„๊ณผ ๋…๋ฆฝ์ โ†’์ •๋ณด ์€๋‹‰

์˜ˆ์ œ 8-3์€ 8-2์™€ ๋งค์šฐ ๋น„์Šทํ•˜์ง€๋งŒ, Student๊ฐ€ Personํด๋ž˜์Šค์˜ ๋น„๊ณต๊ฐœ ์ •์˜์—๋Š” ์˜์กดํ•˜์ง€ ์•Š๋Š”๋‹ค๋Š” ์ฐจ์ด ์กด์žฌโ†’์ž์‹ ํด๋ž˜์Šค ๊ตฌํ˜„์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š๊ณ ๋„ ๋ถ€๋ชจ ํด๋ž˜์Šค ๊ตฌํ˜„ ๋ณ€๊ฒฝ ๊ฐ€๋Šฅ

์˜ˆ์ œ 8-2๋Š” person_t์˜ ์‹ค์ œ ์ •์˜์— ์ ‘๊ทผโ†’์ •๋ณด ์€๋‹‰ ์›๋ฆฌ ์œ„๋ฐ˜ ๊ฐ€๋Šฅ์„ฑ

  • ์˜ˆ์ œ 8-3

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    
    // ์ „๋ฐฉ ์„ ์–ธ
    struct student_t;
    
    // ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ž
    struct student_t* student_new();
    
    // ์ƒ์„ฑ์ž
    void student_ctor(struct student_t*,
                      const char*  /* first name */,
                      const char*  /* last name */,
                      unsigned int /* birth year */,
                      const char*  /* student number */,
                      unsigned int /* passed credits */);
    
    // ์†Œ๋ฉธ์ž
    void student_dtor(struct student_t*);
    
    // ํ–‰์œ„ ํ•จ์ˆ˜
    void student_get_first_name(struct student_t*, char*);
    void student_get_last_name(struct student_t*, char*);
    unsigned int student_get_birth_year(struct student_t*);
    void student_get_student_number(struct student_t*, char*);
    unsigned int student_get_passed_credits(struct student_t*);
    
    #endif
    

    Student ํด๋ž˜์Šค์˜ ์ƒˆ๋กœ์šด ๊ณต์šฉ ์ธํ„ฐํŽ˜์ด์Šค: ์ฒซ ๋ฒˆ์งธ ์ ‘๊ทผ๋ฒ•๊ณผ ๋‹ฌ๋ฆฌ ๋‘ ๋ฒˆ์งธ ์ ‘๊ทผ๋ฒ•์—์„œ๋Š” Student ํด๋ž˜์Šค์˜ ๊ณต์šฉ ์ธํ„ฐํŽ˜์ด์Šค๊ฐ€ ๋ณ€๊ฒฝ๋˜์–ด์•ผ ํ•œ๋‹ค. student_t ํฌ์ธํ„ฐ๋ฅผ person_t ํฌ์ธํ„ฐ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์—†์Œโ†’์—…์บ์ŠคํŒ… ๋ถˆ๊ฐ€๋Šฅโ†’Student ํด๋ž˜์Šค๋Š” Person ํด๋ž˜์Šค์—์„œ ์„ ์–ธํ•œ ๋ชจ๋“  ํ–‰์œ„ ํ•จ์ˆ˜๋ฅผ ๋ฐ˜๋ณตํ•ด์•ผ ํ•จ(p.323๊ณผ ๋น„๊ต)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    
    #include <stdlib.h>
    #include <string.h>
    
    // ๋น„๊ณต๊ฐœ ์ •์˜
    typedef struct {
      char first_name[32];
      char last_name[32];
      unsigned int birth_year;
    } person_t;
    
    // ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ž
    person_t* person_new() {
      return (person_t*)malloc(sizeof(person_t));
    }
    
    // ์ƒ์„ฑ์ž
    void person_ctor(person_t* person,
                     const char* first_name,
                     const char* last_name,
                     unsigned int birth_year) {
      strcpy(person->first_name, first_name);
      strcpy(person->last_name, last_name);
      person->birth_year = birth_year;
    }
    
    // ์†Œ๋ฉธ์ž
    void person_dtor(person_t* person) {
      // ํ•  ์ผ ์—†์Œ
    }
    
    // ํ–‰์œ„ ํ•จ์ˆ˜
    void person_get_first_name(person_t* person, char* buffer) {
      strcpy(buffer, person->first_name);
    }
    
    void person_get_last_name(person_t* person, char* buffer) {
      strcpy(buffer, person->last_name);
    }
    
    unsigned int person_get_birth_year(person_t* person) {
      return person->birth_year;
    }
    

    Person ํด๋ž˜์Šค์˜ ์ƒˆ๋กœ์šด ๊ตฌํ˜„: person_t์˜ ๋น„๊ณต๊ฐœ ์ •์˜๊ฐ€ ์†Œ์Šค ๋‚ด์— ์กด์žฌ, ๋น„๊ณต๊ฐœ ํ—ค๋” ํŒŒ์ผ์ด ์‚ฌ์šฉ๋˜์ง€ ์•Š์Œ(p.321๊ณผ ๋น„๊ต)โ†’Student ํด๋ž˜์Šค ๊ฐ™์€ ํƒ€ ํด๋ž˜์Šค์™€ ์ •์˜๋ฅผ ๊ณต์œ ํ•˜์ง€ ์•Š๊ฒ ๋‹ค๋Š” ๋œป(Person ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์บก์Šํ™”)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    
    #include <stdlib.h>
    #include <string.h>
    
    // 1. person ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๊ณต์šฉ ์ธํ„ฐํŽ˜์ด์Šค
    #include "ExtremeC_examples_chapter8_3_person.h"
    
    // ์ „๋ฐฉ ์„ ์–ธ
    typedef struct {
      char* student_number;
      unsigned int passed_credits;
      // 2. person_t๊ฐ€ ๋ถˆ์™„์ „ํ•œ ํ˜•์‹์ด๊ธฐ ๋•Œ๋ฌธ์— ์—ฌ๊ธฐ์— ํฌ์ธํ„ฐ๊ฐ€ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      struct person_t* person;
    } student_t;
    
    // ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ž
    student_t* student_new() {
      return (student_t*)malloc(sizeof(student_t));
    }
    
    // ์ƒ์„ฑ์ž
    void student_ctor(student_t* student,
                      const char* first_name,
                      const char* last_name,
                      unsigned int birth_year,
                      const char* student_number,
                      unsigned int passed_credits) {
      // 3. ๋ถ€๋ชจ ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹นํ•˜๊ธฐ
      student->person = person_new();
      person_ctor(student->person, first_name,
              last_name, birth_year);
      student->student_number = (char*)malloc(16 * sizeof(char));
      strcpy(student->student_number, student_number);
      student->passed_credits = passed_credits;
    }
    
    // ์†Œ๋ฉธ์ž
    void student_dtor(student_t* student) {
      // ๋จผ์ € ์ž์‹ ๊ฐ์ฒด๋ฅผ ์†Œ๋ฉธ์‹œ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      free(student->student_number);
      // ๊ทธ๋Ÿฐ ๋‹ค์Œ, ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ์†Œ๋ฉธ์ž ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      person_dtor(student->person);
      // ๊ทธ๋ฆฌ๊ณ  ๋ถ€๋ชจ ๊ฐ์ฒด์— ํ• ๋‹น๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      free(student->person);
    }
    
    // 4. ํ–‰์œ„ ํ•จ์ˆ˜
    void student_get_first_name(student_t* student, char* buffer) {
      // person์˜ ํ–‰์œ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      person_get_first_name(student->person, buffer);
    }
    
    void student_get_last_name(student_t* student, char* buffer) {
      // person์˜ ํ–‰์œ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      person_get_last_name(student->person, buffer);
    }
    
    unsigned int student_get_birth_year(student_t* student) {
      // person์˜ ํ–‰์œ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      return person_get_birth_year(student->person);
    }
    
    void student_get_student_number(student_t* student,
                                    char* buffer) {
      strcpy(buffer, student->student_number);
    }
    
    unsigned int student_get_passed_credits(student_t* student) {
      return student->passed_credits;
    }
    

    Student ํด๋ž˜์Šค์˜ ์ƒˆ๋กœ์šด ๊ตฌํ˜„(p.324์™€ ๋น„๊ต)

    1. Person ํด๋ž˜์Šค์˜ ๊ณต์šฉ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํ—ค๋” ํŒŒ์ผ์— ํฌํ•จ
    2. student_t์˜ ์ •์˜ ๋ถ€๋ถ„: ํฌ์ธํ„ฐ ํ•„๋“œ ์ถ”๊ฐ€, ์ฒซ๋ฒˆ์งธ ํ•„๋“œ์ผ ํ•„์š”๋Š” x, ์ƒํ˜ธ๋ณ€ํ™˜ ํ•  ์ˆ˜ ์—†์Œ
    3. ๋ถ€๋ชจ ๊ฐ์ฒด๋ฅผ ์ธ์Šคํ„ด์Šคํ™”
    4. Student ํด๋ž˜์Šค๋Š” ์ž์‹ ์˜ ํ–‰์œ„ ํ•จ์ˆ˜๋“ค์„ ๋…ธ์ถœ, ๋ž˜ํผ ํ•จ์ˆ˜ ๋…ธ์ถœโ†’Student ๊ฐ์ฒด ์ž์ฒด๋กœ๋Š” Person ๊ฐ์ฒด์˜ ๋น„๊ณต๊ฐœ ์†์„ฑ์„ ์•Œ ์ˆ˜ ์—†์Œ
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    
    #include <stdio.h>
    #include <stdlib.h>
    
    #include "ExtremeC_examples_chapter8_3_student.h"
    
    int main(int argc, char** argv) {
      // student ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ณ  ์ƒ์„ฑํ•˜๊ธฐ
      struct student_t* student = student_new();
      student_ctor(student, "John", "Doe",
              1987, "TA5667", 134);
    
      // student ํฌ์ธํ„ฐ๋Š” person ํฌ์ธํ„ฐ๊ฐ€ ์•„๋‹ˆ๋ฉฐ
      // student ๊ฐ์ฒด์— ์žˆ๋Š” ๋น„๊ณต๊ฐœ ๋ถ€๋ชจ ํฌ์ธํ„ฐ์— ์ ‘๊ทผํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ,
      // student์˜ ํ–‰์œ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
      char buffer[32];
      student_get_first_name(student, buffer);
      printf("First name: %s\n", buffer);
    
      student_get_last_name(student, buffer);
      printf("Last name: %s\n", buffer);
    
      printf("Birth year: %d\n", student_get_birth_year(student));
    
      student_get_student_number(student, buffer);
      printf("Student number: %s\n", buffer);
    
      printf("Passed credits: %d\n",
              student_get_passed_credits(student));
    
      // student ๊ฐ์ฒด ์†Œ๋ฉธ ๋ฐ ํ•ด์ œํ•˜๊ธฐ
      student_dtor(student);
      free(student);
    
      return 0;
    }
    

    person.h ํฌํ•จxโ†’Person ํด๋ž˜์Šค์˜ ํ–‰์œ„ ํ•จ์ˆ˜ ์‚ฌ์šฉx(p.325์™€ ๋น„๊ต)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    
    gcc -c ExtremeC_examples_chapter8_3_person.c -o person.o
    gcc -c ExtremeC_examples_chapter8_3_student.c -o student.o
    gcc -c ExtremeC_examples_chapter8_3_main.c -o main.o
    gcc person.o student.o main.o -o ex8_3.out
    ./ex8_3.out
    //First name: John
    //Last name: Doe
    //Birth year: 1987
    //Student number: TA5667
    //Passed credits: 134
    

    ์ถœ๋ ฅ ๊ฒฐ๊ณผ๋Š” ๊ฐ™์Œ

โ˜‘๏ธ ๋‘ ๊ฐ€์ง€ ์ ‘๊ทผ๋ฒ• ๋น„๊ตํ•˜๊ธฐ

  • ์ฒซ ๋ฒˆ์งธ ์ ‘๊ทผ๋ฒ•

    • ํ•ฉ์„ฑ ๊ด€๊ณ„
    • ์ž์‹์˜ ์†์„ฑ ๊ตฌ์กฐ์ฒด ์•ˆ์— ๊ตฌ์กฐ์ฒด ๋ณ€์ˆ˜ ์กด์žฌ
    • ๋ถ€๋ชจ ํด๋ž˜์Šค๊ฐ€ ๋น„๊ณต๊ฐœ ๊ตฌํ˜„์— ์ ‘๊ทผํ•˜๋Š” ๋ฐ์— ์˜์กด
    • ๋ถ€๋ชจ์™€ ์ž์‹์˜ ์ž๋ฃŒํ˜•์€ ๋งค์šฐ ์˜์กด์ 
    • ๋ถ€๋ชจ๊ฐ€ ์˜ค์ง ํ•˜๋‚˜
    • C์˜ ๋‹จ์ผ ์ƒ์† sngle inertance์„ ๊ตฌํ˜„
    • ๋ถ€๋ชจ์˜ ๊ตฌ์กฐ์ฒด ๋ณ€์ˆ˜๋Š” ์ž์‹ ํด๋ž˜์Šค์˜ ์†์„ฑ ๊ตฌ์กฐ์ฒด์˜ ์ฒซ ๋ฒˆ์งธ ํ•„๋“œ
    • ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ํ–‰์œ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ
  • ๋‘ ๋ฒˆ์งธ ์ ‘๊ทผ๋ฒ•

    • ํ•ฉ์„ฑ ๊ด€๊ณ„
    • ๋ถ€๋ชจ์˜ ์†์„ฑ ๊ตฌ์กฐ์ฒด์˜ ๋ถˆ์™„์ „ ์ž๋ฃŒํ˜•์œผ๋กœ๋ถ€ํ„ฐ ๊ตฌ์กฐ์ฒด ํฌ์ธํ„ฐ๋ฅผ ๋‘๋ฏ€๋กœ ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๋น„๊ณต๊ฐœ ๊ตฌํ˜„์— ์˜์กดํ•˜์ง€ ์•Š์Œ
    • ํด๋ž˜์Šค๋“ค์€ ์„œ๋กœ์— ๋Œ€ํ•ด ๋…๋ฆฝ์ 
    • ๋ถ€๋ชจ์˜ ๊ตฌํ˜„ ๋‚ด๋ถ€์— ์žˆ๋Š” ๋ชจ๋“  ๊ฒƒ์€ ์ž์‹์—๊ฒŒ ์ˆจ๊ฒจ์ ธ ์žˆ์Œ
    • ์›ํ•˜๋Š” ๋งŒํผ ๋งŽ์€ ๋ถ€๋ชจ๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋‹ค์ค‘ ์ƒ์†mutpe nhertanceo๋ผ๋Š” ๊ฐœ๋…
    • ๋ถ€๋ชจ ๊ฐ์ฒด์— ๋Œ€ํ•œ ํฌ์ธํ„ฐ๋ฅผ ๊ตฌ์กฐ์ฒด ๋‚ด์˜ ์–ด๋””๋“ 
    • ์ž์‹ ํด๋ž˜์Šค์˜ ์ƒˆ๋กœ์šด ํ–‰์œ„ ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ๋ถ€๋ชจ์˜ ํ–‰์œ„ ํ•จ์ˆ˜๋ฅผ ์ „๋‹ฌ

โญ 8.2 ๋‹คํ–ฅ์„ฑ ์†Œ๊ฐœ

โ“๋‹คํ–ฅ์„ฑ์ด๋ž€ โ†’ ์„œ๋กœ ๋‹ค๋ฅธ ํ–‰์œ„๋ฅผ ๊ฐ–๋Š” ๊ฐ™์€ ์ฝ”๋“œ(๊ณต์šฉ ์ธํ„ฐํŽ˜์ด์Šค)๋ฅผ ๋‘๋Š” ๊ธฐ๋ฒ•์ž…๋‹ˆ๋‹ค.

โ†’ ๋‹คํ–ฅ์„ฑ์„ ํ†ตํ•ด ์ „์ฒด ์ฝ”๋“œ๋ฒ ์ด์Šค๋ฅผ ๋‹ค์‹œ ์ปดํŒŒ์ผํ•˜์ง€ ์•Š๊ณ ๋„ ์ฝ”๋“œ๋ฅผ ์ƒ์†ํ•˜๊ฑฐ๋‚˜ ๊ธฐ๋Šฅ์„ ์ถ”๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Animal, Cat, Duck ์ž๋ฃŒํ˜•์— ๋Œ€ํ•œ ๊ฐ์ฒด ์„ธ ๊ฐœ๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ

    1
    2
    3
    4
    5
    6
    7
    8
    9
    
    struct animal_t*animal = animal_malloc();
    animal_ctor(animal);
    
    struct cat_t*cat = cat_malloc();
    cat_ctor(cat);
    
    struct duck_t*duck = duck_malloc();
    duck_ctor(aduck);
    
    
    • cat๊ณผ duckํด๋ž˜์Šค๋Š” animalํด๋ž˜์Šค์˜ ์ž์‹์ด๋ผ๊ณ  ๊ฐ€์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ ๋‹คํ–ฅ์„ฑ์ด ์—†๋‹ค๋ฉด sound ํ•จ์ˆ˜๋ฅผ ๊ฐ ๊ฐ์ฒด์—์„œ ํ˜ธ์ถœํ–ˆ์„ ๊ฒ๋‹ˆ๋‹ค.
    1
    2
    3
    
    animal_sound(animal);
    cat_sound(cat);
    duck_sound(duck);
    
    • ํ•˜์ง€๋งŒ ๋‹คํ˜•์  ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋œ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.
    1
    2
    3
    
    animal_sound(animal);
    animal_sound((struct animal_t*)cat);
    animal_sound((struct animal_t*)duck);
    
    • animal_sound๊ฐ€ ๋‹คํ˜•์ ์ด๋ผ๋ฉด ๋‹ค๋ฅธ ๊ฐ์ฒด ํฌ์ธํ„ฐ๋ฅผ ์ „๋‹ฌํ–ˆ์„ ๋•Œ ๊ฐ์ž ๋‹ค๋ฅธ ์†Œ๋ฆฌ๊ฐ€ ์ถœ๋ ฅ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ฐ™์€ animal_sound๋ฅผ ์‚ฌ์šฉํ–ˆ์ง€๋งŒ ํฌ์ธํ„ฐ๋Š” ๋‹ค๋ฅธ ๊ฒƒ์œผ๋กœ ์‚ฌ์šฉํ•˜์˜€๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ํ•จ์ˆ˜๋“ค์„ ๋‚ด๋ถ€์—์„œ ๋ถˆ๋Ÿฌ์™”์Šต๋‹ˆ๋‹ค.

    • ์ด ์ฝ”๋“œ๋Š” ๋‹คํ˜•์  ์ฝ”๋“œ๋กœ Animal์ด๋ผ๋Š” ํด๋ž˜์Šค์™€ ํ•จ๊ป˜ Cat , Duck ํด๋ž˜์Šค์™€ ์ƒ์† ๊ด€๊ณ„์ž…๋‹ˆ๋‹ค. duck_t์™€ cat_t ํฌ์ธํ„ฐ๋ฅผ animal_t ํฌ์ธํ„ฐ๋กœ ๋ณ€ํ™˜ํ•˜๋ ค๊ณ  ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    
    typedef struct {
    ...
    }animal_t
    
    typedef struct {
    aniaml_t animal;
    ...
    }cat_t;
    
    typedef struct{
    aniaml_t animal;
    ...
    }duck_t;
    
    • ์ƒ์†์„ ๊ตฌํ˜„ํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ๋ฐฉ๋ฒ•์œผ๋กœ ์ž์‹ ํด๋ž˜์Šค๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค์˜ ๋น„๊ณต๊ฐœ ๊ตฌํ˜„์— ์ ‘๊ทผํ–ˆ์œผ๋ฉฐ, ์—ฌ๊ธฐ์„œ duck_t์™€ cat_t ์†์„ฑ ๊ตฌ์กฐ์ฒด ์ •์˜์˜ ์ฒซ ๋ฒˆ์งธ ํ•„๋“œ๋กœ animal_t ์ž๋ฃŒํ˜•์ธ ๊ตฌ์กฐ์ฒด ๋ณ€์ˆ˜๋ฅผ ๋‘์–ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค.
    • ์ด ์„ค์ •์„ ํ†ตํ•ด์„œ duck_t์™€ cat_t ํฌ์ธํ„ฐ๋ฅผ animal_t ํฌ์ธํ„ฐ๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๋‚œ ๋’ค ๋‘ ์ž์‹ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ํ–‰์œ„ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โ˜‘๏ธ ๋‹คํ–ฅ์„ฑ์ด ํ•„์š”ํ•œ ์ด์œ 

โ†’ ํ˜„์žฌ์˜ ๋กœ์ง์„ ์ž์ฃผ ์ˆ˜์ •ํ•˜๊ณ  ์‹ถ์ง€๋Š” ์•Š์„ ๋•Œ ๋‹คํ–ฅ์„ฑ์„ ์ด์šฉํ•˜๋ฉด ํ•„์š”ํ•œ ๋ณ€๊ฒฝ ํšŸ์ˆ˜๋ฅผ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โ†’ ์ถ”์ƒํ™” ๋•Œ๋ฌธ์— ๋‹คํ–ฅ์„ฑ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ถ”์ƒ์ ์ธ ์ž๋ฃŒํ˜•(ํด๋ž˜์Šค)๋ฅผ ๊ฐ€์งˆ ๋•Œ, ์ž์‹ ํด๋ž˜์Šค์—์„œ๋Š” ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ๋˜์–ด์•ผ ํ•˜๋Š” ํ–‰์œ„๋ฅผ ๊ฐ–๋Š”๋ฐ ์ด๋•Œ ๋‹คํ–ฅ์„ฑ์ด ํ•ต์‹ฌ์ ์ž…๋‹ˆ๋‹ค.

โ˜‘๏ธ C์—์„œ ๋‹คํ˜•์  ํ–‰์œ„๋ฅผ ๊ฐ–๋Š” ๋ฐฉ๋ฒ•

C์—์„œ ๋‹คํ–ฅ์„ฑ์„ ๊ฐ€์งˆ๋ ค๋ฉด ์ƒ์†์„ ๊ตฌํ˜„ํ•˜๋Š” ์ฒซ ๋ฒˆ์งธ ์ ‘๊ทผ๋ฒ•์„ ๊ฐ€์ ธ์•ผํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๋‹คํ–ฅ์  ํ–‰์œ„๋ฅผ ๋‹ฌ์„ฑํ•˜๋ ค๋ฉด ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ์ด์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ์†์„ฑ ๊ตฌ์กฐ์ฒด ๋‚ด์˜ ํ•„๋“œ์— ๋‘์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

  • ์˜ˆ์ œ 8-4

    • Animal ํด๋ž˜์Šค์˜ ๊ณต์šฉ ์ธํ„ฐํŽ˜์ด์Šค

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      
      // File name: ExtremeC_examples_chapter8_4_animal.h
      // Description: Public interface of the animal class
      
      #ifndef EXTREME_C_EXAMPLES_CHAPTER_8_4_ANIMAL_H
      #define EXTREME_C_EXAMPLES_CHAPTER_8_4_ANIMAL_H
      
      // Forward declaration
      struct animal_t;
      
      // Memory allocator
      struct animal_t* animal_new();
      
      // Constructor
      void animal_ctor(struct animal_t*);
      
      // Destructor
      void animal_dtor(struct animal_t*);
      
      // Behavior functions
      void animal_get_name(struct animal_t*, char*);
      void animal_sound(struct animal_t*);
      
      #endif
      
      • Animal ํด๋ž˜์Šค์˜ ๊ณต์šฉ ์ธํ„ฐํŽ˜์ด์Šค์—์„œ๋Š” 2๊ฐœ์˜ ํ–‰์œ„ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.
        • animal_sound ํ•จ์ˆ˜๋Š” ๋‹คํ˜•์ ์œผ๋กœ, ์ž์‹ ํด๋ž˜์Šค์—์„œ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
        • animal_get_name์€ ๋‹คํ˜•์ ์ด์ง€ ์•Š์œผ๋ฉฐ ์ž์‹ ํด๋ž˜์Šค๊ฐ€ ์˜ค๋ฒ„๋ผ์ด๋”ฉ์ด ๋  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.
    • Animal ํด๋ž˜์Šค์˜ ๋น„๊ณต๊ฐœ ํ—ค๋” (Animal ํด๋ž˜์Šค์˜ ์†์„ฑ ๊ตฌ์กฐ์ฒด์— ๊ด€ํ•œ ์‹ค์ œ ์ •์˜ ํฌํ•จ)- ์ƒ์†์„ ๊ตฌํ˜„ํ•˜๋Š” ์ฒซ๋ฒˆ์งธ ์ ‘๊ทผ๋ฒ•์œผ๋กœ ์ทจํ•ฉ๋‹ˆ๋‹ค

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      
      // File name: ExtremeC_examples_chapter8_4_animal_p.h
      // Description: Private defintion of the attribute structure
      //              of the animal class
      
      #ifndef EXTREME_C_EXAMPLES_CHAPTER_8_4_ANIMAL_P_H
      #define EXTREME_C_EXAMPLES_CHAPTER_8_4_ANIMAL_P_H
      
      // ๊ฐ€๋ฆฌํ‚ค๋Š”๋ฐ ํ•„์š”ํ•œ ํ•จ์ˆ˜ ํฌ์ธํ„ฐํ˜•
      // different morphs of animal_sound
      typedef void (*sound_func_t)(void*);
      
      // Forward declaration
      typedef struct {
        char* name;
        // This member is a pointer to the function which
        // performs the actual sound behavior
        sound_func_t sound_func;
      } animal_t;
      
      #endif
      
      • ๋ชจ๋“  ์ž์‹ ํด๋ž˜์Šค๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ ์ƒ์† ๋ฐ›์€ ํ•จ์ˆ˜๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
      • ์˜ค๋ฒ„๋ผ์ด๋”ฉํ•˜๋ ค๋Š” ๊ฐ๊ฐ์˜ ์ž์‹ ํด๋ž˜์Šค์— ๋Œ€ํ•œ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
        • ์ด๋Ÿฌํ•œ ์ด์œ ๋กœ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
      • ์ฆ‰ ๋ชจ๋“  ์ž์‹ ํด๋ž˜์Šค๋Š” animal_sound ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์ž์‹ ๋งŒ์˜ ๋ฒ„์ „์„ ์ œ๊ณต ํ•  ์ˆ˜ ์žˆ๊ณ , ์ž์‹ ํด๋ž˜์Šค๊ฐ€ animal_sound๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉํ–ˆ๋‹ค๋ฉด, ์˜ค๋ฒ„๋ผ์ด๋”ฉ๋œ ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋˜์–ด์•ผํ•˜๊ณ  ์ด๋•Œ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
        • animal_t์˜ ๊ฐ ์ธ์Šคํ„ด์Šค(ํด๋ž˜์Šค์—์„œ ํ˜„์žฌ ์ƒ์„ฑ๋œ ๊ฐ์ฒด)๋Š” animal_sound ํ–‰์œ„ ์ „์šฉ์˜ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ๊ฐ€์งˆ ๊ฒƒ์ด๊ณ , ๊ทธ ํฌ์ธํ„ฐ๋Š” ํด๋ž˜์Šค ๋‚ด์˜ ๋‹คํ˜•์  ํ•จ์ˆ˜์— ๋Œ€ํ•œ ์‹ค์ œ ์ •์˜๋ฅผ ๊ฐ€๋ฆฌํ‚ต๋‹ˆ๋‹ค.
    • Animal ํด๋ž˜์Šค์— ๋Œ€ํ•œ ์ •์˜

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      
      // File name: ExtremeC_examples_chapter8_4_animal.c
      // Description: Private definition of the behavior functions
      //              of the animal class
      
      #include <stdlib.h>
      #include <string.h>
      #include <stdio.h>
      
      #include "ExtremeC_examples_chapter8_4_animal_p.h"
      
      // Default definition of the animal_sound at the parent level
      void __animal_sound(void* this_ptr) { //__animal_sound๋Š” animal_sound ํ•จ์ˆ˜์˜ ๊ธฐ๋ณธ ํ–‰์œ„๊ฐ€ ๋˜์–ด์•ผํ•จ.
        animal_t* animal = (animal_t*)this_ptr;
        printf("%s: Beeeep\n", animal->name);
      }
      
      // Memory allocator
      animal_t* animal_new() {
        return (animal_t*)malloc(sizeof(animal_t));
      }
      
      // Constructor
      void animal_ctor(animal_t* animal) {
        animal->name = (char*)malloc(10 * sizeof(char));
        strcpy(animal->name, "Animal");
        // Set the function pointer to point to the default definition
        animal->sound_func = __animal_sound;
      } //__animal_sound์˜ ์ฃผ์†Œ๋ฅผ animal ๊ฐ์ฒด์˜ ํ•จ์ˆ˜ ํฌ์ธํ„ฐ์ธ sound_func์— ์ €์žฅ
      // ์ด ์„ค์ •์œผ๋กœ ๋ชจ๋“  ์ž์‹ ๊ฐ์ฒด๋Š” ์ด ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋ฅผ ์ƒ์†ํ•˜๊ณ  ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๋Š” __animal_sound์˜ ๊ธฐ๋ณธ ์ •์˜๋ฅผ ๊ฐ€๋ฅดํ‚ต๋‹ˆ๋‹ค.
      
      // Destructor
      void animal_dtor(animal_t* animal) {
        free(animal->name);
      }
      
      // Behavior functions
      void animal_get_name(animal_t* animal, char* buffer) {
        strcpy(buffer, animal->name);
      }
      
      void animal_sound(animal_t* animal) {
        // ํ•จ์ˆ˜ ํฌ์ธํ„ฐ๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ํ•จ์ˆ˜ ํ˜ธ์ถœํ•จ.
        animal->sound_func(animal);
      } //sound_func๊ฐ€ ๋‹ค๋ฅธ ํ•จ์ˆ˜๋ฅผ ๊ฐ€๋ฆฌํ‚ฌ ๋•Œ animal_sound๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋ฉด sound_func๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” ํ•จ์ˆ˜๊ฐ€ ํ˜ธ์ถœ๋จ.
        //sound_func = __animal_sound์— ํ•ด๋‹นํ•˜๋Š” sound ํ–‰์œ„์˜ ์‹ค์ œ ์ •์˜๋ฅผ ๊ฐ€๋ฆฌํ‚ค๋Š” ํ•จ์ˆ˜ ํฌ์ธํ„ฐ ํ•„๋“œ
      
    • Cat ํด๋ž˜์Šค์˜ ๊ณต์šฉ ์ธํ„ฐํŽ˜์ด์Šค

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      
      // File name: ExtremeC_examples_chapter8_4_cat.h
      // Description: Public interface of the cat class
      
      #ifndef EXTREME_C_EXAMPLES_CHAPTER_8_4_CAT_H
      #define EXTREME_C_EXAMPLES_CHAPTER_8_4_CAT_H
      
      // Forward declaration
      struct cat_t;
      
      // Memory allocator
      struct cat_t* cat_new();
      
      // Constructor
      void cat_ctor(struct cat_t*);
      
      // Destructor
      void cat_dtor(struct cat_t*);
      
      // All behavior functions are inherited from the animal class.
      
      #endif
      
      • Cat ํด๋ž˜์Šค๋Š” ๋ถ€๋ชจ ํด๋ž˜์Šค์ธ Animal ํด๋ž˜์Šค๋กœ๋ถ€ํ„ฐ sound๋ฅผ ์ƒ์† ๋ฐ›์Šต๋‹ˆ๋‹ค.
    • Cat ํด๋ž˜์Šค์˜ ๋น„๊ณต๊ฐœ ๊ตฌํ˜„

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      
      // File name: ExtremeC_examples_chapter8_4_cat.c
      // Description: Private defintions of the class cat
      
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      #include "ExtremeC_examples_chapter8_4_animal.h"
      #include "ExtremeC_examples_chapter8_4_animal_p.h"
      
      typedef struct {
        animal_t animal;
      } cat_t;
      
      // Define a new behavior for the cat's sound
      void __cat_sound(void* ptr) {  //cat์˜ sound๋ฅผ ์œ„ํ•œ ์ƒˆ๋กœ์šด ํ•จ์ˆ˜์ธ __cat_sound๋ฅผ ์ •์˜
        animal_t* animal = (animal_t*)ptr;
        printf("%s: Meow\n", animal->name);
      }
      
      // Memory allocator
      cat_t* cat_new() {
        return (cat_t*)malloc(sizeof(cat_t));
      }
      
      // Constructor
      void cat_ctor(cat_t* cat) {
        animal_ctor((struct animal_t*)cat);
        strcpy(cat->animal.name, "Cat");
        // Point to the new behavior function. Overriding
        // is actually happening here.
        cat->animal.sound_func = __cat_sound; //์˜ค๋ฒ„๋ผ์ด๋”ฉ ๋ฐœ์ƒ
      }
      
      // Destructor
      void cat_dtor(cat_t* cat) {
        animal_dtor((struct animal_t*)cat);
      }
      
      • cat ๊ฐ์ฒด๋Š” **animal_sound ๋Œ€์‹ ์— ์‹ค์ œ๋กœ **cat_sound๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ์˜ค๋ฒ„๋ผ์ด๋”ฉ์„ ๋ฐœ์ƒ์‹œ์ผฐ์Šต๋‹ˆ๋‹ค.
    • Duck ํด๋ž˜์Šค์˜ ๊ณต์šฉ ์ธํ„ฐํŽ˜์ด์Šค

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      
      // File name: ExtremeC_examples_chapter8_4_duck.h
      // Description: Public interface of the duck class
      
      #ifndef EXTREME_C_EXAMPLES_CHAPTER_8_4_DUCK_H
      #define EXTREME_C_EXAMPLES_CHAPTER_8_4_DUCK_H
      
      // Forward declaration
      struct duck_t;
      
      // Memory allocator
      struct duck_t* duck_new();
      
      // Constructor
      void duck_ctor(struct duck_t*);
      
      // Destructor
      void duck_dtor(struct duck_t*);
      
      // All behavior functions are inherited from the animal class.
      
      #endif
      
    • Duck ํด๋ž˜์Šค์˜ ๋น„๊ณต๊ฐœ ๊ตฌํ˜„

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      
      // File name: ExtremeC_examples_chapter8_4_duck.c
      // Description: Private defintions of the class duck
      
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      #include "ExtremeC_examples_chapter8_4_animal.h"
      #include "ExtremeC_examples_chapter8_4_animal_p.h"
      
      typedef struct {
        animal_t animal;
      } duck_t;
      
      // Define a new behavior for the duck's sound
      void __duck_sound(void* ptr) {
        animal_t* animal = (animal_t*)ptr;
        printf("%s: Quacks\n", animal->name);
      }
      
      // Memory allocator
      duck_t* duck_new() {
        return (duck_t*)malloc(sizeof(duck_t));
      }
      
      // Constructor
      void duck_ctor(duck_t* duck) {
        animal_ctor((struct animal_t*)duck);
        strcpy(duck->animal.name, "Duck");
        // Point to the new behavior function. Overriding
        // is actually happening here.
        duck->animal.sound_func = __duck_sound;
      }
      
      // Destructor
      void duck_dtor(duck_t* duck) {
        animal_dtor((struct animal_t*)duck);
      }
      
      • Duck ํด๋ž˜์Šค ๋˜ํ•œ ์ƒˆ๋กœ์šด ๋น„๊ณต๊ฐœ ํ–‰์œ„ ํ•จ์ˆ˜์ธ __duck_sound๋Š” duck์— ํ•œ์ •๋œ ์†Œ๋ฆฌ๋ฅผ ๋‚ด๋„๋ก soundํ–‰์œ„์˜ ๊ธฐ๋ณธ ์ •์˜๋ฅผ ์˜ค๋ฒ„๋ผ์ด๋”ฉ ํ–ˆ์Šต๋‹ˆ๋‹ค.

    • ๋ฉ”์ธ ์‹œ๋‚˜๋ฆฌ์˜ค

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      
      // File name: ExtremeC_examples_chapter8_4_main.c
      // Description: Main scenario which calls the
      // polymorphic functions
      
      #include <stdio.h>
      #include <stdlib.h>
      #include <string.h>
      
      // Only public interfaces
      #include "ExtremeC_examples_chapter8_4_animal.h"
      #include "ExtremeC_examples_chapter8_4_cat.h"
      #include "ExtremeC_examples_chapter8_4_duck.h"
      
      int main(int argc, char** argv) {
        struct animal_t* animal = animal_new();
        struct cat_t* cat = cat_new();
        struct duck_t* duck = duck_new();
      
        animal_ctor(animal);
        cat_ctor(cat);
        duck_ctor(duck);
      
        animal_sound(animal);  //๋‹ค๋ฅธ ํฌ์ธํ„ฐ๋ฅผ ์ „๋‹ฌํ•ด ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋‹คํ˜•์  ํ–‰์œ„๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
        animal_sound((struct animal_t*)cat);
        animal_sound((struct animal_t*)duck);
      
        animal_dtor(animal);
        cat_dtor(cat);
        duck_dtor(duck);
      
        free(duck);
        free(cat);
        free(animal);
        return 0;
      }
      
      • mainํ•จ์ˆ˜๋Š” animal, Cat, Duck ํด๋ž˜์Šค์˜ ๊ณต์šฉ์ธํ„ฐํŽ˜์ด์Šค๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
        • mainํ•จ์ˆ˜๋Š” ์ด๋“ค ํด๋ž˜์Šค์˜ ๋‚ด๋ถ€ ๊ตฌํ˜„์— ๊ด€ํ•ด์„œ๋Š” ์•„๋ฌด๊ฒƒ๋„ ๋ชจ๋ฅด๊ธฐ ๋•Œ๋ฌธ์— ๋‹ค๋ฅธ ํฌ์ธํ„ฐ๋ฅผ ์ „๋‹ฌํ•ด animal_sound ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋ฉด ๋‹คํ˜•์  ํ–‰์œ„๊ฐ€ ์ž‘๋™ํ•˜๋Š” ๋ฐฉ์‹์„ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค.
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      
      gcc -c ExtremeC_examples_chapter8_4_animal.c -o animal.o
      gcc -c ExtremeC_examples_chapter8_4_cat.c -o cat.o
      gcc -c ExtremeC_examples_chapter8_4_duck.c -o duck.o
      gcc -c ExtremeC_examples_chapter8_4_main.c -o main.o
      gcc animal.o cat.o duck.o main.o -o ex8_4.out
      ./ex8_4.out
      
      /********************************************************
      Animal: Beeeep
      Cat: Meow
      Duck: Quacks
      *********************************************************/
      
This post is licensed under CC BY 4.0 by the author.