*추신, 그냥 필자가 멋대로 테스트해본것으로 정말 이런지는 연습을 하면서 익혀보는 중이다.
C언어와 C++는 비슷하다.
필자는 클래스(Class)는 구조체(Struct)의 변형체로써 특정 기능(정확하게는 함수를 간단하게 구조체에 넣는 기능)이 붙어 있는 것이 클래스라고 본다.
클래스의 변수를 맴버변수라고 하는데. 구조체의 변수 또한 맴버변수라고 한다.
물론, 클래스에는 메소드가 있고, 구조체는 메소드랑 함수가 들어갈 수 없다.[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 | #include <stdio.h> class Person { public: int nums; public: Person() { nums = 10; } }; class BaseballPlayer: public Person { public: int score; public: BaseballPlayer():Person() { score = 50; } }; class Employee: public Person { public: int hits; public: Employee():Person() { nums = 600; hits = 100; } }; int main(void) { Person *person = new Person(); BaseballPlayer *player = new BaseballPlayer(); Employee *employee = new Employee(); printf("%d\n", person->nums); printf("%d\n", player->score); printf("%d\n", player->nums); printf("%d\n", employee->hits); printf("%d\n", employee->nums); return 0; } | cs |
test1.cpp
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 | #include <stdio.h> class Person { public: int nums; public: Person() { nums = 10; } }; class BaseballPlayer: public Person { public: int score; public: BaseballPlayer():Person() { score = 50; } }; class Employee: public Person { public: int hits; public: Employee():Person() { nums = 600; hits = 100; } }; int main(void) { Person *person = new Person(); BaseballPlayer *player = new BaseballPlayer(); Employee *employee = new Employee(); printf("%d\n", person->nums); printf("%d\n", player->score); printf("%d\n", player->nums); printf("%d\n", employee->hits); printf("%d\n", employee->nums); return 0; } | cs |
test.c
이렇게 해보았다.
여기서, gcc --save-temp과, g++ --save-temp를 이용해서 처리하는 것이다.
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 | .file "test.c" .text .globl _mkPerson .def _mkPerson; .scl 2; .type 32; .endef _mkPerson: pushl %ebp movl %esp, %ebp subl $24, %esp movl $4, (%esp) call _malloc movl %eax, %edx movl 8(%ebp), %eax movl %edx, (%eax) movl 8(%ebp), %eax movl (%eax), %eax movl $10, (%eax) leave ret .globl _mkBaseballPlayer .def _mkBaseballPlayer; .scl 2; .type 32; .endef _mkBaseballPlayer: pushl %ebp movl %esp, %ebp subl $24, %esp movl $8, (%esp) call _malloc movl %eax, %edx movl 8(%ebp), %eax movl %edx, (%eax) movl 8(%ebp), %eax movl (%eax), %eax movl %eax, (%esp) call _mkPerson movl 8(%ebp), %eax movl (%eax), %eax movl $50, 4(%eax) leave ret .globl _mkEmployee .def _mkEmployee; .scl 2; .type 32; .endef _mkEmployee: pushl %ebp movl %esp, %ebp subl $24, %esp movl $8, (%esp) call _malloc movl %eax, %edx movl 8(%ebp), %eax movl %edx, (%eax) movl 8(%ebp), %eax movl (%eax), %eax movl %eax, (%esp) call _mkPerson movl 8(%ebp), %eax movl (%eax), %eax movl (%eax), %eax movl $600, (%eax) movl 8(%ebp), %eax movl (%eax), %eax movb $100, 4(%eax) leave ret .def ___main; .scl 2; .type 32; .endef .section .rdata,"dr" LC0: .ascii "%d\12\0" .text .globl _main .def _main; .scl 2; .type 32; .endef _main: pushl %ebp movl %esp, %ebp andl $-16, %esp subl $32, %esp call ___main leal 28(%esp), %eax movl %eax, (%esp) call _mkPerson leal 24(%esp), %eax movl %eax, (%esp) call _mkBaseballPlayer leal 20(%esp), %eax movl %eax, (%esp) call _mkEmployee movl 28(%esp), %eax movl (%eax), %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf movl 24(%esp), %eax movl 4(%eax), %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf movl 24(%esp), %eax movl (%eax), %eax movl (%eax), %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf movl 20(%esp), %eax movzbl 4(%eax), %eax movsbl %al, %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf movl 20(%esp), %eax movl (%eax), %eax movl (%eax), %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf movl $0, %eax leave ret .ident "GCC: (tdm-1) 4.9.2" .def _malloc; .scl 2; .type 32; .endef .def _printf; .scl 2; .type 32; .endef | cs |
test.s
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 | .file "test1.cpp" .section .text$_ZN6PersonC2Ev,"x" .linkonce discard .align 2 .globl __ZN6PersonC2Ev .def __ZN6PersonC2Ev; .scl 2; .type 32; .endef __ZN6PersonC2Ev: pushl %ebp movl %esp, %ebp subl $4, %esp movl %ecx, -4(%ebp) movl -4(%ebp), %eax movl $10, (%eax) leave ret .section .text$_ZN6PersonC1Ev,"x" .linkonce discard .align 2 .globl __ZN6PersonC1Ev .def __ZN6PersonC1Ev; .scl 2; .type 32; .endef __ZN6PersonC1Ev: pushl %ebp movl %esp, %ebp subl $4, %esp movl %ecx, -4(%ebp) movl -4(%ebp), %eax movl $10, (%eax) leave ret .section .text$_ZN14BaseballPlayerC1Ev,"x" .linkonce discard .align 2 .globl __ZN14BaseballPlayerC1Ev .def __ZN14BaseballPlayerC1Ev; .scl 2; .type 32; .endef __ZN14BaseballPlayerC1Ev: pushl %ebp movl %esp, %ebp subl $4, %esp movl %ecx, -4(%ebp) movl -4(%ebp), %eax movl %eax, %ecx call __ZN6PersonC2Ev movl -4(%ebp), %eax movl $50, 4(%eax) leave ret .section .text$_ZN8EmployeeC1Ev,"x" .linkonce discard .align 2 .globl __ZN8EmployeeC1Ev .def __ZN8EmployeeC1Ev; .scl 2; .type 32; .endef __ZN8EmployeeC1Ev: pushl %ebp movl %esp, %ebp subl $4, %esp movl %ecx, -4(%ebp) movl -4(%ebp), %eax movl %eax, %ecx call __ZN6PersonC2Ev movl -4(%ebp), %eax movl $600, (%eax) movl -4(%ebp), %eax movl $100, 4(%eax) leave ret .def ___main; .scl 2; .type 32; .endef .section .rdata,"dr" LC0: .ascii "%d\12\0" .text .globl _main .def _main; .scl 2; .type 32; .endef _main: pushl %ebp movl %esp, %ebp pushl %ebx andl $-16, %esp subl $32, %esp call ___main movl $4, (%esp) call __Znwj movl %eax, %ebx movl %ebx, %ecx call __ZN6PersonC1Ev movl %ebx, 28(%esp) movl $8, (%esp) call __Znwj movl %eax, %ebx movl %ebx, %ecx call __ZN14BaseballPlayerC1Ev movl %ebx, 24(%esp) movl $8, (%esp) call __Znwj movl %eax, %ebx movl %ebx, %ecx call __ZN8EmployeeC1Ev movl %ebx, 20(%esp) movl 28(%esp), %eax movl (%eax), %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf movl 24(%esp), %eax movl 4(%eax), %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf movl 24(%esp), %eax movl (%eax), %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf movl 20(%esp), %eax movl 4(%eax), %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf movl 20(%esp), %eax movl (%eax), %eax movl %eax, 4(%esp) movl $LC0, (%esp) call _printf movl $0, %eax movl -4(%ebp), %ebx leave ret .ident "GCC: (tdm-1) 4.9.2" .def __Znwj; .scl 2; .type 32; .endef .def _printf; .scl 2; .type 32; .endef | cs |
test1.s
이렇게 되어 있다.
여기서, test.s와 test1.s을 비교해봤다.
여기서 소스상에서 많이 차이가 없어 보인다.
여기서 차이가 있다면, cpp에서 생성자가 기본적으로 존재하고 [__ZN6PersonC1Ev], 이 후에 생성되는 생성자는 [__ZN6PersonC2Ev]가 되면서 추가되어서 생성자가 생성된다.
하지만, test1.cpp에서 Person 클래스에 생성자를 추가하지 않으면, 해당 소스에서 [__ZN6PersonC1Ev ] 같은 함수가 사라지고, 그냥 메모리 할당이 되는 것으로 된다.
하지만, 이것은 c에서는 생성자라는 함수가 있는 것이고 구조체가 그대로 사용되는 방식은 클래스랑 구조체랑 다른게 없다는걸 알게 되었다.
그래서 C++에서는 각각 구조체 변수를 사용할 수 있게 되어 있고 그것을 프로그래머가 알고 있다. 라는 가정으로 작업하게 만들기 때문에 super랑 base를 지원하지 않고, 다중 상속을 지원하는 것같다.
'연습' 카테고리의 다른 글
wxWidgets 설치하기 (0) | 2018.04.03 |
---|---|
Firebase의 OAuth인증 방식(Javascript) (0) | 2018.04.02 |
wxWidget에서 오류나는 것으로 보이는 주의사항. (0) | 2017.06.30 |
안드로이드 Oauth2을 이용한 로그인 어플 만들기. (0) | 2017.04.06 |
한글과 컴퓨터를 설치한 후에 브라우져의 업로드 중 강제 종료 막기. (0) | 2017.04.05 |