도순씨의 코딩일지
C++ :: 멤버함수와 가상함수의 동작원리 본문
먼저 단순한 코드를 하나 살펴보도록 하겠습니다.
🌼 멤버함수의 위치
⭐️RealObjUnder1.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#include <iostream>
using namespace std;
class Data{
private:
int data;
public:
Data(int num) : data(num) {}
void ShowData() { cout << "Data: " << data << endl;}
void Add(int num) {data += num;}
};
int main(void){
Data obj(15);
obj.Add(17);
obj.ShowData();
return 0;
}
|
cs |
⭐️RealObjUnder1.cpp 실행결과
1
|
Data: 32
|
cs |
위 예제를 C언어 스타일의 구조체와 전역함수를 이용해서 바꾸어보겠습니다.
⭐️ RealObjUnder2.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
|
#include <iostream>
using namespace std;
// 클래스 Data를 흉내낸 영역
typedef struct Data{
int data;
void (*ShowData)(Data*);
void (*Add)(Data*, int);
}Data;
void ShowData(Data* THIS) { cout << "Data: " << THIS -> data << endl;}
void Add(Data* THIS, int num) {THIS -> data += num;}
// 적절히 변경된 main 함수
int main(void){
Data obj1 = {15, ShowData, Add};
Data obj2 = {7, ShowData, Add};
obj1.Add(&obj1, 17);
obj2.Add(&obj2, 9);
obj1.ShowData(&obj1);
obj2.ShowData(&obj2);
return 0;
}
|
cs |
⭐️ RealObjUnder2.cpp 실행 결과
1
2
|
Data: 32
Data: 16
|
cs |
위 코드에서 두 개의 구조체 변수(객체)가 함수를 공유하고 있습니다. 객체가 생성되면 멤버변수는 객체 내에 존재하지만, 멤버 함수는 메모리 다른 공간에 별도로 위치합니다. 그리고 이 함수가 정의된 클래스의 모든 객체에서 메모리 공간을 사용하는 형태입니다.
🌼 가상함수의 동작원리와 가상함수 테이블
하나의 코드를 살펴보며 동작원리를 익혀보도록 합시다.
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
|
#include <iostream>
using namespace std;
class AAA{
private:
int num;
public:
virtual void Func1() {cout << "Func1"<<endl;}
virtual void Func2() {cout << "Func2" << endl;}
};
class BBB : public AAA{
private:
int num2;
public:
virtual void Func1() {cout << "BBB::Func1"<< endl;}
void Func3() {cout << "Func3"<< endl;}
};
int main(void){
AAA * aptr = new AAA();
aptr -> Func1();
BBB * bptr = new BBB();
bptr -> Func1();
return 0;
}
|
cs |
먼저 AAA 클래스를 살펴봅시다. virtual로 선언된 가상함수 두 개가 존재합니다. 이렇듯 한 개 이상의 가상함수를 포함하는 클래스에 대해서는 컴파일러가 '가상함수 테이블'이라는 것을 만듭니다. 가상함수 테이블은 실제 호출될 함수의 위치를 담고 있습니다.
key | value |
void AAA::Func1( ) | 0x1024번지 |
void AAA::Func2( ) | 0x2048번지 |
이러한 가상함수 테이블을 통해서 호출할 위치를 알 수 있습니다. 가상함수 테이블에는 오버라이딩 된 가상함수의 정보는 존재하지 않습니다.
'𝐏𝐑𝐎𝐆𝐑𝐀𝐌𝐌𝐈𝐍𝐆 > 𝐂++' 카테고리의 다른 글
C++ :: 디폴트 대입 연산자, 배열의 인덱스 연산자 오버로딩, const 함수 오버로딩 (0) | 2020.08.30 |
---|---|
C++ :: 연산자 오버라이딩, 단항 연산자의 오버로딩, 전위증가와 후위증가 오버로딩 (0) | 2020.08.29 |
C++ :: 객체 포인터의 참고관계, 가상함수, 순수 가상함수, 가상 소멸자 (0) | 2020.08.27 |
C++ :: protected 상속, private 상속, IS-A 관계, HAS-A 관계 (2) | 2020.08.26 |
C++ :: 상속(Inheritance) (0) | 2020.08.25 |
Comments