티스토리 뷰
가상함수
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 |
#include "pch.h"
#include <iostream>
class Base
{
public:
void Display()
{
printf("Base의 Display()\n");
}
};
class Derived : public Base
{
public:
void Display()
{
printf("Derived의 Display()\n");
}
};
int main()
{
Base* pObj = new Derived;
pObj->Display();
delete pObj;
_getwch();
} |
cs |
실행결과>
main() 에서 pObj->Display() 는 Base 클래스의 멤버함수 Display() 를 호출한다.
아래 기계어 코드처럼 new 로 객체를 만들고 11번줄에 Base::Display 라고 표시되어 있다.
1
2
3
4
5
6
7
8
9
10
11 |
00028 6a 01 push 1
0002a e8 00 00 00 00 call ??2@YAPAXI@Z ; operator new
0002f 83 c4 04 add esp, 4
00032 89 85 2c ff ff
ff mov DWORD PTR $T2[ebp], eax
00038 8b 85 2c ff ff
ff mov eax, DWORD PTR $T2[ebp]
0003e 89 45 f8 mov DWORD PTR _pObj$[ebp], eax
00041 8b 4d f8 mov ecx, DWORD PTR _pObj$[ebp]
00044 e8 00 00 00 00 call ?Display@Base@@QAEXXZ ; Base::Display |
cs |
일반 멤버함수에 대한 호출은 컴파일러가 컴파일할때 객체변수의 자료형을 보고 함수 호출이 결정되며, 변경되지 않는다. 이것을 정적 바인딩이라고 한다.
일반 멤버함수에 대해서 기억해야 할것은 멤버함수를 호출할때 사용한 객체 자료형이지, 객체가 누군지가 중요한것은 아니다.
만약, 실제 객체에 구현된 멤버함수를 호출하려면 아래 코드 7번줄 처럼 부모 클래스에 virtual 키워드를 사용한다.
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 |
#include "pch.h"
#include <iostream>
class Base
{
public:
virtual void Display() { };
};
class Derived : public Base
{
public:
virtual void Display()
{
printf("Derived의 Display()\n");
}
};
int main()
{
Base* pObj = new Derived;
pObj->Display();
delete pObj;
_getwch();
} |
cs |
실행결과>
아래 기계어 코드 12번줄에 Derived 클래스의 멤버함수가 호출되는 걸 알 수 있다.
1
2
3
4
5
6
7
8
9
10
11
12 |
...
00028 6a 04 push 4
0002a e8 00 00 00 00 call ??2@YAPAXI@Z ; operator new
0002f 83 c4 04 add esp, 4
00032 89 85 2c ff ff
ff mov DWORD PTR $T2[ebp], eax
00038 83 bd 2c ff ff
ff 00 cmp DWORD PTR $T2[ebp], 0
0003f 74 13 je SHORT $LN3@main
00041 8b 8d 2c ff ff
ff mov ecx, DWORD PTR $T2[ebp]
00047 e8 00 00 00 00 call ??0Derived@@QAE@XZ |
cs |