π’ chap9. μΆμνμ C++μ OPP
β 9.1 μΆμν
- OOPμμμ μΆμν : μΆμ μλ£νμ λ€λ£¨λ κ², ν΄λμ€ κΈ°λ°μ κ°μ²΄μ§ν₯μμ μΆμ μλ£νμ μΆμ ν΄λμ€λ₯Ό λ€λ£¨λ κ²μ λλ€.
- μΆμ ν΄λμ€ : κ°μ²΄λ₯Ό μμ±νκ³ λμ, μ¬μ©νκΈ°μλ μμ§ μ€λΉλμ§λ μλ£λμ§λ μμ μν.
λ¬Έμ₯μ λͺ μ¬κ° ν΄λμ€λΌκ³ λ³΄κ³ , ν΄λμ€ κ°μλ λ€μκ³Ό κ°μ κ΄κ³κ° μ±λ¦½ν μ μμ΅λλ€.
- μΈκ°μ μ¬κ³Όλ₯Ό λ¨Ήλλ€.
- μΈκ°μ μ€λ μ§λ₯Ό λ¨Ήλλ€.
- μΈκ°μ κ³ΌμΌμ λ¨Ήλλ€.
- μ΄λ κ³ΌμΌμ μ¬κ³Όμ μ€λ μ§λ₯Ό ν¬ν¨νλ λΆλͺ¨ μΆμ ν΄λμ€μ λλ€. κ·Έλ¦¬κ³ μ¬κ³Όμ μ€λ μ§λ ꡬμ μλ£νμ΄λΌκ³ ν©λλ€.
- κ³ΌμΌμ λ μΆμμ μΌλ‘ λ§λ€μ΄ μΈκ°μ μν κ°λ₯ ν κ²μ λ¨Ήλλ€.
- μν κ°λ₯ν κ²μ κ³ΌμΌλ³΄λ€ λΆλͺ¨ μΆμ ν΄λμ€μ λλ€.
- κ³Όλν μΆμν : νμν μμ€λ³΄λ€ λ μΆμμ μΈ μΆμ μλ£ν, νμν μ¬νλ³΄λ€ λ μΆμ μλ£νμ μμ±νλ κ².
- μΆμν μμΉ : νλ‘κ·Έλ¨μ μ€μν κ° κΈ°λ₯μ μμ€ μ½λμ μ€μ§ ν λΆλΆμμλ§ κ΅¬νλμ΄μΌ νλ€. λΉμ·ν κΈ°λ₯μ λ³κ°μ μ½λμμ μνν λλ μΌλ°μ μΌλ‘ λ€μν λΆλΆμ μΆμνν΄ νλλ‘ κ²°ν©νλ νΈμ΄ μ’λ€.
νλ‘κ·Έλλ° μΈμ΄μμ μμκ³Ό λ€νμ±μ μΆμνλ₯Ό μν΄ νμν©λλ€.
μμμ μνκ°λ₯ν κ²κ³Ό κ°μ μΆμ ν΄λμ€λ μ¬κ³Ό λ±μ μν κ°λ₯ν κ² κ΄λ ¨ ꡬμ ν΄λμ€μ λν λΆλͺ¨νμ μ΄λ©° μμμ μν΄ μ΄λ£¨μ΄ μ§λλ€.
λ€νμ± μμ μ€μν μν μ ν©λλ€. μΆμ μλ£νμλ ν΄λΉ μΆμν μμ€μμ κΈ°λ³Έ ꡬνμ κ°μ§ λͺ»νλ νμκ° μμ΅λλ€. μμλ‘ λ¨Ήμ μ μλκ²(Eatable) ν΄λμ€μμ eatable_get_tasteμ κ°μ νμ ν¨μλ₯Ό μ¬μ©ν΄ ꡬνλ μμ±μΌλ‘μμ λ§μ (taste)μ λ¨Ήμ μ μλ κ² (Eatable) κ°μ²΄λ₯Ό λ€λ£° λ μ νν κ°μ κ°μ§ μ μμ΅λλ€. β λ¨Ήμ μ μλ κ²μλ λ§μ λν μμ±μ μ μ ν μ μμ΅λλ€. λ€νμ±μΌλ‘μ νμ΄λΈλ€.
μμ ν΄λμ€κ° μΆ©λΆν ꡬ체μ μΌ λλ§ μ μν μ μμ΅λλ€. μ¬κ³Ό κ°μ²΄λ λ§μ λν΄ λ¨λ§μ λ°νν μ μμ΅λλ€. λ€νμ±μ λ°λ‘ μ΄ μ§μ μμ λμμ΄ λ©λλ€.
μμ ν΄λμ€κ° μ€λ²λΌμ΄λ©ν μ μλ νμ ν¨μλ₯Ό κ°μ ν¨μλΌκ³ λΆλ μ΅λλ€. κ°μ ν¨μλ μ μκ° μμ μμ μλ μμ΅λλ€. κ°μ ν¨μλ μμ μ ν΄λμ€λ₯Ό μΆμν ν©λλ€.
- νΉμ μμ€μμ λμ± μΆμνν΄μ, μμ±κ³Ό κΈ°λ³Έ μ μλ₯Ό κ°μ§ μλ κ°μ ν¨μλ§μ ν¬ν¨νλ ν΄λμ€κΉμ§ λλ¬νμ΅λλ€. μ΄λ¬ν ν΄λμ€λ₯Ό μΈν°νμ΄μ€λΌκ³ ν©λλ€. μ¦ μΈν°νμ΄μ€λ κΈ°λ₯μ λ ΈμΆνμ§λ§ ꡬνμ μ ν λ ΈμΆνμ§ μμΌλ©°, μΌλ°μ μΌλ‘ μννΈμ¨μ΄ νλ‘μ νΈμμ λ€μν μ»΄ν¬λνΈ μ¬μ΄μ μμ‘΄μ±μ λ§λλλ° μ¬μ©ν©λλ€. μμλ‘ λ¨Ήλ μ(Eater)μ λ¨Ήμ μ μλ κ²(Eatable)ν΄λμ€κ° μΈν°νμ΄μ€μ λλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
typedef enum {SWEET, SOUR} taste_t;
//ν¨μ ν¬μΈν° μλ£ν
typedef taste_t (*get_taste_func_t)(void*);
typedef struct {
// κ°μ ν¨μμ λν μ μλ₯Ό κ°λ¦¬ν€λ ν¬μΈν°
get_taste_func_t get_taste_func;
} eatable_t;
eatable_t* eatable_new() {...} // ν λΉμ ν¨μ
void eatable_ctor(eatable_t* eatable){
// κ°μ ν¨μμ λν κΈ°λ³Έ μ μλ μμ΅λλ€.
eatable->get_taste_func = NULL;
}
// κ°μ νμ ν¨μ
taste_t eatable_get_taste(eatable_t* eatable){
return eatable->get_taste_func(eatable);
}
- μΈν°νμ΄μ€μ λν μ μμ μ€κ³ κ΄μ μμ μ΄ν΄ν μ μλ μ΄μ μΈμλ κΈ°λ³Έμ μΌλ‘ λ¨Ήμ μ μλ κ²(Eatable) μΈν°νμ΄μ€μμ κ°μ²΄λ₯Ό μμ±ν΄μλ μ λ©λλ€. λ¨Ήμ μ μλ κ²(Eatable) μΈν°νμ΄μ€μμ κ°μ²΄λ₯Ό μμ±νλ κ²μ΄ Cμ κ΄μ μμ κ°λ₯νμ§λ§ μΆ©λμ΄ λ°μν©λλ€. μ λ ν΄μλ μλ©λλ€.
1
2
3
4
5
6
eatable_t *eatable = eatable_new();
eatable_ctor(eatable);
taste_t taste = eatable_get_taste(eatable); // μΈκ·Έλ©ν
μ΄μ
μ€λ₯
taste_t taste = eatable_get_taste((eatable_t)orange); //
free(eatable);
μΆμ μλ£νμΌλ‘ κ°μ²΄λ₯Ό μμ±νμ§ μμΌλ €λ©΄ ν΄λμ€μ κ³΅μ© μΈν°νμ΄μ€μμ ν λΉμ ν¨μλ₯Ό μ κ±°ν©λλ€. 8μ₯μ μ κ·Όλ²μ κΈ°μ΅νλ€λ©΄, ν λΉμ ν¨μλ₯Ό μ κ±°ν¨μΌλ‘μ¨ μ€μ§ μμ ν΄λμ€λ§μ΄ λΆλͺ¨μ μμ± κ΅¬μ‘°μ²΄λ‘λΆν° κ°μ²΄λ₯Ό μμ±ν μ μμ΅λλ€.
μΈλΆ μ½λκ° λ μ΄μ λΆλͺ¨μ μμ± κ΅¬μ‘°μ²΄λ‘λΆν° κ°μ²΄λ₯Ό μμ±ν μ μμ΅λλ€. μλ₯Ό λ€μ΄, eatable_tλ‘λΆν° κ°μ²΄λ₯Ό μμ±νμ§ λͺ»νκ² νλ €κ³ ν©λλ€. μμ± κ΅¬μ‘°μ²΄λ₯Ό μ μΈ μμ λμ΄ λΆμμ μλ£νμΌλ‘ λ§λ€κ³ , κ³΅μ© λ©λͺ¨λ¦¬ ν λΉμμΈ eatable_newλ₯Ό ν΄λμ€μμ μ κ±°ν΄μΌ ν©λλ€.
λ§€μ° λμ μΆμν μμ€μμλ λͺ¨λ ν¨μ ν¬μΈν°κ° NULLμΈ μΈν°νμ΄μ€λ₯Ό κ°μ΅λλ€. μΆμ μλ£νμΌλ‘λΆν° μΈλΆ μ½λκ° κ°μ²΄λ₯Ό μμ±νμ§ λͺ»νκ² νλ €λ©΄ κ³΅μ© μΈν°νμ΄μ€μμ ν λΉμ ν¨μλ₯Ό μ κ±°ν΄μΌ ν©λλ€.
β 9.2 C++μ κ°μ²΄μ§ν₯ ꡬμ±λ¬Ό
βοΈ 9.2.1 μΊ‘μν
- OPP κΈ°λ²μ μ¬μ©ν Cμ OPPκ°λ μΌλ‘ ꡬνν C++ λ νλ‘κ·Έλ¨μ λν΄ μμ±λ μ΄μ λΈλ¦¬ λͺ λ Ήμ΄λ₯Ό λΉκ΅νκ² μ΅λλ€.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <stdio.h>
typedef struct {
int width;
int length;
} rect_t;
int rect_area(rect_t* rect) {
return rect->width * rect->length;
}
int main(int argc, char**argv){
rect_t r;
r.width = 10;
r.length = 25;
int area = rect_area(&r);
printf("Area: %d\n", area);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>
class Rect{
public:
int Area() {
return width * length;
}
int width;
int length;
};
int main(int argc, char** argv){
Rect r;
r.width = 10;
r.length = 25;
int area = r.Area();
std::cout << "Area: " << area << std::endl;
return 0;
}
1
2
gcc -S ExtremeC_examples_chapter9_1.c -o ex9_1_c.s
g++ -S ExtremeC_exampes_chapter9_1.cpp -o ex9_1_cpp.s
- Cμ C++ μ΄μ λΈλ¦¬ μ½λ λΉκ΅
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
ubuntu@DESKTOP-FFH31MN:~/Extreme-C/ch09-abstraction-and-oop-in-c++$ cat ex9_1_c.s
.file "ExtremeC_examples_chapter9_1.c"
.text
.globl rect_area
.type rect_area, @function
rect_area:
.LFB0:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movl (%rax), %edx
movq -8(%rbp), %rax
movl 4(%rax), %eax
imull %edx, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size rect_area, .-rect_area
.section .rodata
.LC0:
.string "Area: %d\n"
.text
.globl main
.type main, @function
main:
.LFB1:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $48, %rsp
movl %edi, -36(%rbp)
movq %rsi, -48(%rbp)
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
movl $10, -16(%rbp)
movl $25, -12(%rbp)
leaq -16(%rbp), %rax
movq %rax, %rdi
call rect_area
movl %eax, -20(%rbp)
movl -20(%rbp), %eax
movl %eax, %esi
leaq .LC0(%rip), %rax
movq %rax, %rdi
movl $0, %eax
call printf@PLT
movl $0, %eax
movq -8(%rbp), %rdx
subq %fs:40, %rdx
je .L5
call __stack_chk_fail@PLT
.L5:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1:
.size main, .-main
.ident "GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0"
.section .note.GNU-stack,"",@progbits
.section .note.gnu.property,"a"
.align 8
.long 1f - 0f
.long 4f - 1f
.long 5
0:
.string "GNU"
1:
.align 8
.long 0xc0000002
.long 3f - 2f
2:
.long 0x3
3:
.align 8
4:
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
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
ubuntu@DESKTOP-FFH31MN:~/Extreme-C/ch09-abstraction-and-oop-in-c++$ cat ex9_1_cpp.s
.file "ExtremeC_examples_chapter9_1.cpp"
.text
.local _ZStL8__ioinit
.comm _ZStL8__ioinit,1,1
.section .text._ZN4Rect4AreaEv,"axG",@progbits,_ZN4Rect4AreaEv,comdat
.align 2
.weak _ZN4Rect4AreaEv
.type _ZN4Rect4AreaEv, @function
_ZN4Rect4AreaEv:
.LFB1731:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movq %rdi, -8(%rbp)
movq -8(%rbp), %rax
movl (%rax), %edx
movq -8(%rbp), %rax
movl 4(%rax), %eax
imull %edx, %eax
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1731:
.size _ZN4Rect4AreaEv, .-_ZN4Rect4AreaEv
.section .rodata
.LC0:
.string "Area: "
.text
.globl main
.type main, @function
main:
.LFB1732:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $48, %rsp
movl %edi, -36(%rbp)
movq %rsi, -48(%rbp)
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
movl $10, -16(%rbp)
movl $25, -12(%rbp)
leaq -16(%rbp), %rax
movq %rax, %rdi
call _ZN4Rect4AreaEv
movl %eax, -20(%rbp)
leaq .LC0(%rip), %rax
movq %rax, %rsi
leaq _ZSt4cout(%rip), %rax
movq %rax, %rdi
call _ZStlsISt11char_traitsIcEERSt13basic_ostreamIcT_ES5_PKc@PLT
movq %rax, %rdx
movl -20(%rbp), %eax
movl %eax, %esi
movq %rdx, %rdi
call _ZNSolsEi@PLT
movq _ZSt4endlIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_@GOTPCREL(%rip), %rdx
movq %rdx, %rsi
movq %rax, %rdi
call _ZNSolsEPFRSoS_E@PLT
movl $0, %eax
movq -8(%rbp), %rdx
subq %fs:40, %rdx
je .L5
call __stack_chk_fail@PLT
.L5:
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE1732:
.size main, .-main
.type _Z41__static_initialization_and_destruction_0ii, @function
_Z41__static_initialization_and_destruction_0ii:
.LFB2235:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $16, %rsp
movl %edi, -4(%rbp)
movl %esi, -8(%rbp)
cmpl $1, -4(%rbp)
jne .L8
cmpl $65535, -8(%rbp)
jne .L8
leaq _ZStL8__ioinit(%rip), %rax
movq %rax, %rdi
call _ZNSt8ios_base4InitC1Ev@PLT
leaq __dso_handle(%rip), %rax
movq %rax, %rdx
leaq _ZStL8__ioinit(%rip), %rax
movq %rax, %rsi
movq _ZNSt8ios_base4InitD1Ev@GOTPCREL(%rip), %rax
movq %rax, %rdi
call __cxa_atexit@PLT
.L8:
nop
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2235:
.size _Z41__static_initialization_and_destruction_0ii, .-_Z41__static_initialization_and_destruction_0ii
.type _GLOBAL__sub_I_main, @function
_GLOBAL__sub_I_main:
.LFB2236:
.cfi_startproc
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
movl $65535, %esi
movl $1, %edi
call _Z41__static_initialization_and_destruction_0ii
popq %rbp
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE2236:
.size _GLOBAL__sub_I_main, .-_GLOBAL__sub_I_main
.section .init_array,"aw"
.align 8
.quad _GLOBAL__sub_I_main
.hidden __dso_handle
.ident "GCC: (Ubuntu 11.4.0-1ubuntu1~22.04) 11.4.0"
.section .note.GNU-stack,"",@progbits
.section .note.gnu.property,"a"
.align 8
.long 1f - 0f
.long 4f - 1f
.long 5
0:
.string "GNU"
1:
.align 8
.long 0xc0000002
.long 3f - 2f
2:
.long 0x3
3:
.align 8
βοΈ 9.2.2 μμ
- μμ
- 첫 λ²μ§Έ μ κ·Όλ²
- μμ ν΄λμ€μ ν¬μΈν°λ λΆλͺ¨ ν΄λμ€μ ν¬μΈν°λ‘ ν λΉν μ μμ
- μμ ν΄λμ€λ λΆλͺ¨ ν΄λμ€μ λΉκ³΅κ° μ μμ μ κ·Όν μ μμ
- μμμ μμ± κ΅¬μ‘°μ²΄ μμ ꡬ쑰체 λ³μλ₯Ό λλ€ β λ¨μΌ μμ
- λ λ²μ§Έ μ κ·Όλ²
- λΆλͺ¨μ μμ± κ΅¬μ‘°μ²΄μ λΆμμ μλ£νμΌλ‘λΆν° ꡬ쑰체 ν¬μΈν°λ₯Ό λ
- λΆλͺ¨ ν΄λμ€μ λΉκ³΅κ° ꡬνμ μμ‘΄νμ§ μμ β λ€μ€ μμ (C++ κ°λ₯)
- 첫 λ²μ§Έ μ κ·Όλ²
C κ³Ό C++ λ²μ μ μμ μ°¨μ΄μ
- C μΈμ΄
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_chapter9_2.c // Description: Inheritance in C #include <string.h> typedef struct { char c; char d; } a_t; typedef struct { a_t parent; char str[5]; } b_t; int main(int argc, char** argv) { b_t b; b.parent.c = 'A'; b.parent.d = 'B'; strcpy(b.str, "1234"); // We need to set a break point at this line. return 0; }
- C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// File name: ExtremeC_examples_chapter9_2.cpp // Description: Inheritance in C++ #include <string.h> class A { public: char c; // A char d; // B }; class B : public A { public: char str[5]; }; // 1234 int main(int argc, char** argv) { B b; b.c = 'A'; b.d = 'B'; strcpy(b.str, "1234"); // We need to set a break point at this line. return 0; }
1 2
gcc -g ExtremeC_examples_chapter9_2.c -o ex9_2_c.out gdb ./ex9_2_c.out
1 2
g++ -g ExtremeC_examples_chapter9_2.cpp -o ex9_2_cpp.out gdb ./ex9_2_cpp.out
- C++ μμ νμ ν¨μμ μμ±μ ν΄λμ€ μμ ν¨κ» λμλ€κ³ ν·κ°λ¦¬λ©΄ μλ¨ (κ·Όλ° μ΄ μμ μλ νμ ν¨μκ° μλ€κ³ νμ..)
- νμ ν¨μμ μμ±μ ν΄λμ€μμ λ³κ°λ‘ μ·¨κΈλ¨
- ν΄λμ€ λ΄μ μμΉμ μκ΄μμ΄ μμ±μ μΈμ λ νΉμ κ°μ²΄μ λν΄ κ°μ λ©λͺ¨λ¦¬ λΈλ‘ μμμ μμ§λ¨
- ν¨μλ μμ±κ³Όλ μΈμ λ λ 립μ μΌλ‘ μ‘΄μ¬ν¨ β μ묡μ μΊ‘μν
Cμμ μμμ ꡬννλ 첫 λ²μ§Έ μ κ·Όλ²μμ λ€μ€ μμμ΄ λμ§ μλ μ΄μ
1 2 3 4 5 6 7 8 9 10 11 12 13
typedef struct {...} a_t; typedef struct {...} b_t; typedef struct { a_t a; b_t b; ... } c_t; c_t c_obj; a_t* a_ptr = (a_t*)&c_obj; b_t* b_ptr = (b_t*)&c_obj; c_t* c_ptr = &c_obj;
- c_t ν΄λμ€λ a_t μ b_t ν΄λμ€ λͺ¨λ μμνλ €κ³ νλ€β
- ν΄λμ€ μ μΈ ν λ€μμ c_obj κ°μ²΄λ₯Ό λ§λ€μλ€
- μλ‘ λ€λ₯Έ ν¬μΈν°λ λ§λ€μλ€
- π¨ μ΄λ¬ν ν¬μΈν°λ λͺ¨λ λ°λμ κ°μ μ£Όμλ₯Ό κ°λ¦¬μΌμΌ νλ€
- BUT a_ptr κ³Ό c_ptr ν¬μΈν°λ a_t λ° c_t ν΄λμ€μ μ΄λ νμ ν¨μμλ μμ νκ² μ¬μ© κ°λ₯
- b_ptr ν¬μΈν°λ a_t κ°μ²΄μ ν΄λΉνλ c_t ν΄λμ€ λ΄μ νλλ₯Ό κ°λ¦¬ν€λ―λ‘ μ¬μ©νκΈ° μν
- b_ptr ν¬μΈν° ν΅ν΄ b_t μμ μλ νλλ‘ μ κ·Όνλ €κ³ νλ€λ©΄ μ μλμ§ μμ νμλ‘ λ¨
μλλ μ¬λ°λ₯Έ νλλ₯Ό κ°λ¦¬ν€λλ‘ μΊμ€ν (λ³ν) μ μ λ°μ΄νΈ ν μμλ€
1 2 3 4 5 6 7 8 9 10 11 12 13 14
typedef struct {...} a_t; typedef struct {...} b_t; typedef struct { a_t a; b_t b; ... } c_t; c_t c_obj; a_t* a_ptr = (a_t*)&c_obj; // β¬οΈ λ°μ λ°λ b_t* b_ptr = (b_t*)(&c_obj + sizeof(a_t)); c_t* c_ptr = &c_obj;
- π¨ c_obj μ μ£Όμμ λν a_t κ°μ²΄μ ν¬κΈ°λ₯Ό μΆκ°ν¨
- c_t λ΄λΆμ b νλλ₯Ό κ°λ¦¬ν€λ ν¬μΈν°κ° λλ€
- νλ²ν : μλ£νμ λ³ννκΈ° μν΄ μ‘΄μ¬νλ©°, μμ μμμλ λ©λͺ¨λ¦¬ μ£Όμμ ν΄λΉνλ μ μ‘κ°μ μμ νμ§λ μμ!
- ν λΉ μ΄νμλ κ²°κ΅ μ€λ₯Έμͺ½μ μ£Όμκ° μΌμͺ½μΌλ‘ 볡μ¬λλ€
- π¨ c_obj μ μ£Όμμ λν a_t κ°μ²΄μ ν¬κΈ°λ₯Ό μΆκ°ν¨
- c_t ν΄λμ€λ a_t μ b_t ν΄λμ€ λͺ¨λ μμνλ €κ³ νλ€β
C++ μμμ λ€μ€ μμ
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
// File name: ExtremeC_examples_chapter9_3.cpp // Description: Multiple inheritance in C++ #include <string.h> class A { public: char a; // A char b[4]; // BBB }; class B { public: char c; // C char d; // D }; class C { public: char e; // E char f; // F }; class D : public A, public B, public C { public: char str[5]; // 1234 }; int main(int argc, char** argv) { D d; d.a = 'A'; strcpy(d.b, "BBB"); d.c = 'C'; d.d = 'D'; d.e = 'E'; d.f = 'F'; strcpy(d.str, "1234"); A* ap = &d; B* bp = &d; C* cp = &d; D* dp = &d; // We need to set a break point at this line. return 0; }
1 2
g++ -g ExtremeC_examples_chapter9_3.cpp -o ex9_3.out gdb ./ex9_3.out
- μμ±μ μλ‘ μΈμ ν κ³³μ μμ
- λΆλͺ¨ ν΄λμ€μ λν μ¬λ¬ κ°μ²΄κ° d κ°μ²΄μ λ©λͺ¨λ¦¬ λ μ΄μμκ³Ό κ°μ κ³³ λ΄λΆμ μμμ λνλ
- ap, bp, cp, dp ν¬μΈν°λ β
- C++ μμλ μμ ν¬μΈν°λ₯Ό λΆλͺ¨ ν¬μΈν°λ‘ ν λΉν λ (μ μΊμ€ν ) μ묡μ μΌλ‘ νλ³ν κ°λ₯
- $4 λ‘ λνλλ d κ°μ²΄μ λν μμ μ£Όμλ₯Ό 보μ¬μ€
- $1 λ‘ λνλλ ap κ° κ°λ¦¬ν€λ μ£Όμμ κ°μ β C++ μμ D ν΄λμ€μ μμ± κ΅¬μ‘°μ²΄μ λμνλ 첫 λ²μ§Έ νλλ‘μ¨ A μλ£νμ λν κ°μ²΄λ₯Ό λλ€λ μ μ΄ λͺ νν΄μ§
- ν¬μΈν°μ μλ μ£Όμμ x λͺ λ Ήμ΄λ‘ μ»μ κ²°κ³Όλ₯Ό ν λλ‘, B μλ£νκ³Ό C μλ£νμ κ°μ²΄λ κ°μ²΄ dμ μνλ λ©λͺ¨λ¦¬ λ μ΄μμκ³Ό κ°μ κ³³μ μμ
- μμ μ£Όμλ C++ μμμ νλ³νμ΄ μλ μμ μ΄ μλλΌλ μ μ λνλ
- μλ£νμ λ³νν λ μ μ‘νλ μ£Όμμ λν ν¬μΈν° μ°μ°μ μνν μ μμμ 보μ¬μ€
- EX) bp ν¬μΈν°λ₯Ό ν λΉν λ,
5λ°μ΄νΈ λλ sizeof(A) κ° dμ μ£Όμμ μΆκ°
λλ€ - C μμ λ€μ€ μμμ ꡬννλ κ³Όμ μμ λ°κ²¬λλ λ¬Έμ λ₯Ό 극볡νλ €λ κ²..
- C++ μ΄λ€ ν¬μΈν°λ μ°μ μ°μ° νμ μμ΄ λͺ¨λ νμ ν¨μ λ΄μμ μ½κ² μ¬μ© ν μ μμ
- But,, C μ νλ³ν μ²λΌ C++ μ νλ³νλ μλμ μΌ κ²μ΄λΌ κ°μ νλ€λ©΄,, λ€λ₯Ό κ²μ β
- EX) bp ν¬μΈν°λ₯Ό ν λΉν λ,
- μμ±μ μλ‘ μΈμ ν κ³³μ μμ
βοΈ 9.2.3 λ€νμ±
- C μμ λ€νμ μΈ νμ ν¨μλ κ°λ¨ν¨
C++ μμ λ€νμ±μ κ°μ§λ €λ©΄ λ 볡μ‘ν λ©μ»€λμ¦ μ¬μ©ν¨
C μ½λμμ κ°μ ν¨μκ° μ μΈ λ° μ μλλ λ°©μ
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
// ν¨μ ν¬μΈν° μλ£ν μ μνκΈ° typedef void* (*func_1_t)(void*, ...); typedef void* (*func_2_t)(void*, ...); ... typedef void* (*func_n_t)(void*, ...); // λΆλͺ¨ ν΄λμ€μ λν μμ± κ΅¬μ‘°μ²΄ typedef struct { // μμ± ... // ν¨μμ λν ν¬μΈν° func_1_t func_1; func_2_t func_2; ... func_n_t func_t; } parent_t; // κ°μ νμ ν¨μμ λν κΈ°λ³Έ λΉκ³΅κ° μ μ void* __default_func_1(void* parent, ...) { // κΈ°λ³Έ μ } void* __default_func_2(void* parent, ...) { // κΈ°λ³Έ μ } ... void* __default_func_n(void* parent, ...) { // κΈ°λ³Έ μ } // μμ±μ void parent_ctor(parent_t *parent) { // μμ± μ΄κΈ°ννκΈ° ... // κ°μ νμ ν¨μμ λν κΈ°λ³Έ μ μ μ€μ νκΈ° parent->func_1 = __default_func_1; parent->func_2 = __default_func_2; ... parent->func_n = __default_func_n; } // 곡μ©μΈ λΉκ°μ νμ ν¨μ void* parent_non_virt_func_1(parent_t* parent, ...) { // Code } void* parent_non_virt_func_2(parent_t* parent, ...) { // Code } ... void* parent_non_virt_func_m(parent_t* parent, ...) { // Code } // μ€μ κ³΅μ© κ°μ νμ ν¨μλ€ void* parent_func_1(parent_t* parent, ...) { return parent->func_1(parent, ...); } void* parent_func_2(parent_t* parent, ...) { return parent->func_2(parent, ...); } ... void* parent_func_n(parent_t* parent, ...) { return parent->func_n(parent, ...); }
- λΆλͺ¨ ν΄λμ€λ μμ± κ΅¬μ‘°μ²΄ λ΄λΆμ ν¨μ ν¬μΈν°μ λν λͺ©λ‘μ κ°κ³ μμ΄μΌ ν¨
- λΆλͺ¨ ν΄λμ€μ μ΄λ¬ν ν¨μ ν¬μΈν°λ κ°μ ν¨μμ λν κΈ°λ³Έ μ μλ₯Ό κ°λ¦¬ν΄
- κ·Έλ μ§ μμΌλ©΄ NULL κ° κ°μ§
- μ μλ μμ¬ ν΄λμ€λ m μ΄λΌλ λΉκ°μ νμ ν¨μμ n μ΄λΌλ κ°μ νμ ν¨μ κ°μ§
- λΉκ°μ ν¨μλ λ€νμ μ΄μ§ μμ
1 2
//ꡬν λμ κ°μν¨μμ NULL (0)κ°μ λμ νλ©΄ ν΄λΉ ν¨μλ μμ κ°μν¨μκ° λ©λλ€ virtual void function() = 0;
- λΉκ°μ ν¨μλ₯Ό νΈμΆν΄ λ€μν νμλ₯Ό μ»μ μ μμ
- μ¦, λΉκ°μ ν¨μμ λν νΈμΆμ λ¨μν ν¨μ νΈμΆμ μ§λμ§ μμΌλ©°!
- μ μ λ΄λΆμ λ‘μ§λ§μ μνν λΏ λ€λ₯Έ ν¨μλ‘ νΈμΆμ μ λ¬νμ§ μμ
- κ°μ ν¨μλ λΆλͺ¨ λλ μμ μμ±μμ μν΄ μ€μ λ μ μ ν ν¨μλ‘ νΈμΆμ λ€μ μ λ¬ν΄μΌ ν¨
1 2 3 4 5
// C++μμ κ°μ ν¨μλ virtual ν€μλλ₯Ό μ¬μ©νμ¬ μ μΈν©λλ€. virtual function(){ ... }
- μμλ κ°μ ν¨μμ μΌλΆλ₯Ό μμ ν΄λμ€κ° λ€μ μ μνλ €λ©΄ κ°μ ν¨μ ν¬μΈν°λ₯Ό μ λ°μ΄νΈ ν΄μΌ ν¨
- λΉκ°μ ν¨μλ λ€νμ μ΄μ§ μμ
μμ ν΄λμ€κ° λͺλͺ κ°μ ν¨μλ₯Ό μ€λ²λΌμ΄λ© νλ λ²μ λνλ
μμ ν΄λμ€κ° λΆλͺ¨ ν΄λμ€λ‘λΆν° μμλ°μ κ°μ ν¨μλ₯Ό μ€λ²λΌμ΄λ© νλ λ°©λ²
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
// λΆλͺ¨ ν΄λμ€μ κ΄λ ¨λ λͺ¨λ κ²μ ν¬ν¨νμΈμ typedef struct { parent_t parent; // μμ μμ± ... } child_t; void* __child_func_4(void* parent, ...) { // μ€λ²λΌμ΄λ© μ μ } void* __child_func_7(void* parent, ...) { // μ€λ²λΌμ΄λ© μ μ } void child_ctor(child_t* child) { parent_ctor((parent_t*)child); // μμ μμ± μ΄κΈ°ννκΈ° ... // ν¨μμ λν ν¬μΈν° μ λ°μ΄νΈ νκΈ° child->parent.func_4 = __child_func_4; child->parent.func_7 = __child_func_7; } // μμμ νμ ν¨μ ...
- μμ ν΄λμ€λ λΆλͺ¨μ μμ± κ΅¬μ‘°μ²΄ μμ μλ λͺλͺ ν¬μΈν°μ λν μ
λ°μ΄νΈλ§ νμ
- C++ μμλ λΉμ·ν μ κ·Όλ² μ·¨ν¨
- virtual ν€μλλ₯Ό μ¬μ©ν΄ νμ ν¨μλ₯Ό κ°μμΌλ‘ μ μΈ ν λ C++ λ ν¨μ ν¬μΈν°μ λ°°μ΄μ λ§λ λ€
- κ°κ°μ κ°μ ν¨μμ λν΄ ν¨μ ν¬μΈν° μμ± νλλ₯Ό μΆκ°νμ
- C++ μμλ μ΄λ¬ν ν¬μΈν°λ₯Ό λλλ° λ μ리ν¨
- π¨ κ°μ ν μ΄λΈ λλ vtable μ΄λΌλ λ°°μ΄λ§ μ¬μ©ν¨
- κ°μ ν μ΄λΈμ κ°μ²΄κ° μμ±λλ €κ³ ν λ λ§λ€μ΄μ§λ€
- κ°μ ν μ΄λΈμ κΈ°μ΄ ν΄λμ€μ λν μμ±μλ₯Ό νΈμΆν λ μ²μ μΆκ° λ¨
- κ·Έ λ€μ, μμ ν΄λμ€μ μμ±μμ μΌλΆκ° λλ€
- κ°μ ν μ΄λΈμ μμ±μμμλ§ μΆκ°λλ λ§νΌ, λΆλͺ¨ λ° μμ ν΄λμ€ λͺ¨λ μμ±μμμ λ€νμ λ©μλλ₯Ό νΈμΆνμ§ μμμΌ ν¨
- ν¬μΈν°κ° μ λ°μ΄νΈ λμ§ μμμ μλ μκ³ , νλ¦° μ μλ₯Ό κ°λ¦¬ν¬ μ μμ
- C++ μμλ μ΄λ¬ν ν¬μΈν°λ₯Ό λλλ° λ μ리ν¨
- μμ ν΄λμ€λ λΆλͺ¨μ μμ± κ΅¬μ‘°μ²΄ μμ μλ λͺλͺ ν¬μΈν°μ λν μ
λ°μ΄νΈλ§ νμ
βοΈ 9.2.4 μΆμ ν΄λμ€
- C++ μμ μΆμνλ μμ κ°μ ν¨μλ₯Ό μ¬μ©ν μ μμ
C++ μμ λ©€λ² ν¨μλ₯Ό κ°μ ν¨μλΌκ³ μ μνκ³ μ΄λ₯Ό 0μΌλ‘ λλ€λ©΄, μμ κ°μ ν¨μλ₯Ό μ μ ν κ²!
C++μ Eatable μΈν°νμ΄μ€
1 2 3 4 5 6 7
enum class Taste { Sweet, Sour }; // μΈν°νμ΄μ€ class Eatable { public: virtual Taste GetTaste() = 0; }
- Eatable ν΄λμ€ λ΄λΆμ 0 μΌλ‘ μ€μ ν GetTaste λΌλ κ°μ ν¨μκ° μμ
- GetTaste λ μμ κ°μ ν¨μ μ΄λ©°, μ 체 ν΄λμ€λ₯Ό μΆμν ν¨
- Eatable μλ£νμΌλ‘λΆν° λ μ΄μ κ°μ²΄λ₯Ό μμ± ν μ μμΌλ©°, C++ κ° μ΄λ₯Ό νμ©νμ§ μμ
- Eatable μ μΈν°νμ΄μ€μΈλ°, Eatable μ λͺ¨λ λ©€λ² ν¨μκ° μμνκ² κ°μμ΄κΈ° λλ¬Έ
- μ΄ ν¨μλ μμ ν΄λμ€μ μν΄ μ€λ²λΌμ΄λ© λ μ μμ
C++μ Eatable μΈν°νμ΄μ€λ₯Ό ꡬννλ μμ ν΄λμ€ (GetTaste ν¨μλ₯Ό μ€λ²λΌμ΄λ© νλ ν΄λμ€)
1 2 3 4 5 6 7 8 9 10 11 12 13 14
enum class Taste { Sweet, Sour }; // μΈν°νμ΄μ€ class Eatable { public: virtual Taste GetTaste() = 0; } class Apple : public Eatable { public: Taste GetTaste() override { return Taste::Sweet; } };
- μμ κ°μ ν¨μλ κ°μ ν¨μμ μλΉν λΉμ·ν¨
- μ€μ μ μμ λν μ£Όμλ κ°μ ν¨μμ λ§μ°¬κ°μ§ λ°©μμΌλ‘ κ°μ ν μ΄λΈ λ΄μ μμ
- μμ κ°μ ν¨μμ λν ν¬μΈν°μ μ΄κΉκ°μ NULL
- μΌλ°μ μΈ κ°μ ν¨μμ ν¬μΈν°μλ λ€λ¦
- μΌλ°μ μΈ κ°μ ν¨μμ ν¬μΈν°λ μμ±μ΄ μ§νλλ λμ κΈ°λ³Έ μ μλ₯Ό κ°λ¦¬μΌμΌ ν¨
- μΆμ μλ£νμ λν΄μ μ무κ²λ μμ§ λͺ»νλ C μ»΄νμΌλ¬μ λ¬λ¦¬ - C++ μ»΄νμΌλ¬λ μΆμ μλ£νμ μκ³ μμ - λ§μ½, μΆμ μλ£νμΌλ‘λΆν° κ°μ²΄λ₯Ό μμ±νλ €κ³ νλ€λ©΄ μ»΄νμΌ μ€λ₯ λ°μ
μμ κ°μ ν¨μμ λν ν¬μΈν°μ μ΄κΉκ°μ NULL
- μΌλ°μ μΈ κ°μ ν¨μμ ν¬μΈν°μλ λ€λ¦
- μΌλ°μ μΈ κ°μ ν¨μμ ν¬μΈν°λ μμ±μ΄ μ§νλλ λμ κΈ°λ³Έ μ μλ₯Ό κ°λ¦¬μΌμΌ ν¨
π¨ μΆμ ν΄λμ€λ λ¨Όμ μμμ ν΅ν΄ νμ ν΄λμ€λ₯Ό λ§λ€κ³ , λ§λ νμ ν΄λμ€μμ μμ κ°μ ν¨μλ₯Ό λͺ¨λ μ€λ²λΌμ΄λ©νκ³ λμμΌ λΉλ‘μ νμ ν΄λμ€μ μΈμ€ν΄μ€λ₯Ό μμ±ν μ μκ² λ©λλ€. (νμ§λ§ μΆμ ν΄λμ€ νμ μ ν¬μΈν°μ μ°Έμ‘°λ λ°λ‘ μ¬μ© κ°λ₯)
β 9.3 λ§λ¬΄λ¦¬
- μΆμ μλ£νκ³Ό μΈν°νμ΄μ€λ₯Ό λ€λ£Έ
- μ΄λ₯Ό ν΅ν΄ μΈν°νμ΄μ€ λλ μΆμμ μΈ ν΄λμ€λ₯Ό κ°μ§ μ μμ
- μ΄ λΆλΆμ μΈ μΆμ ν΄λμ€λ λ€νμ±μ κ°λ λ ꡬ체μ μΈ μμ ν΄λμ€ λ° λ€λ₯Έ νμλ₯Ό λ§λ€ λ μ¬μ© κ°λ₯
- OOP κΈ°λ₯μ λμ νκΈ° μν΄ Cμμ μ¬μ©νλ κΈ°λ²μ κ΄ν μΆλ ₯ κ²°κ³Όλ₯Ό g++ μ μΆλ ₯ κ²°κ³Όμ λΉκ΅νκ³ , κ·Έ κ²°κ³Όκ° μΌλ§λ λΉμ·νμ§ μ€λͺ ν¨ (λ§€μ° μ μ¬ν¨)
- κ°μ ν μ΄λΈ μμΈν λ€λ£Έ
- μμ κ°μ ν¨μ (C++ κ°λ μ΄μ§λ§ C μλ ν΄λΉνλ κ°λ μμ) κ° κΈ°λ³Έ μ μλ₯Ό κ°μ§ μλ κ°μ νμλ₯Ό μ μΈνκΈ° μν΄ μ¬μ©νλ λ°©λ² λ³΄μ¬μ€