*추신, 그냥 필자가 멋대로 테스트해본것으로 정말 이런지는 연습을 하면서 익혀보는 중이다.

 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를 지원하지 않고, 다중 상속을 지원하는 것같다.

Posted by JunkMam
,