Computer Security

#8 C++ 다형성 기법 1 본문

프로그래밍/C++

#8 C++ 다형성 기법 1

쿠리 Kuri 2022. 6. 19. 18:30

다형성


칼 객체, 대포 객체, 총 객체를 attack() 분류한 구성에서는 무기 객체에서 attack() 함수를 실질적으로 구현할 필요가 없다. 이럴 때 무기 객체를 추상 클래스(Abstract Class)로 구현하면 효과적으로 설계를 할 수 있다.

 

자식 클래스에서 오버라이딩의 문제점


자식 클래스에서 멤버 함수를 재정의하여 사용하는 것은 일반적으로 정상적으로 동작한다.

하지만 포인터 변수로 객체에 접근할 때는 예상치 못한 결과가 발생할 수 있다.
C++ 컴파일러는 포인터 변수가 가리키고 있는 변수의 타입을 기준으로 함수를 호출하지 않고, 포인터의 타입을 기준
으로 함수를 호출한다.

따라서 A라는 객체를 가리키는 포인터 변수는 A 객체의 멤버 함수만을 호출할 수 있다.

 

함수의 바인딩

- 함수를 만들어 컴파일을 하면 각각의 코드가 메모리 어딘가에 저장된다.

그리고 함수를 호출하는 부분에는 그 함수가 저장된 메모리 번지수(주소값)이 저장된다.

 

프로그램 실행 → 함수 호출 → 함수가 저장된 주소로 점프 → 함수 실행 → 원래 위치

 

위 과정에서 함수를 호출하는 부분에 함수가 위치한 메모리 번지로 연결시켜 주는 것을 바인딩(Binding) 이라고 한다.

 

 

- 함수를 바인딩하는 2가지 방법

(1) 정적 바인딩 (일반 함수)

컴파일 시간에 호출될 함수로 점프할 주소가 결정되어 바인딩 되는 것.

(2) 동적 바인딩 (가상 함수)

실행 파일을 만들 때 바인딩 되지 않고 보류 상태 둔다.

점프할 메모리 번지를 저장하기 위한 메모리 공간(4 byte)을 가지고 있다가 런타임에 결정.

단점 : 타입 체킹으로 인한 수행 속도 저하 / 메모리 공간 낭비

C++는 특정한 함수를 호출할 때 해당 함수의 루틴이 기록된 메모리 주소를 알아야 한다.

특정한 함수를 호출하는 소스코드에서 실제로 함수가 정의된 메모리 공간을 찾기 위해서는 바인딩(Binding) 과정이 필요하다.
일반적으로 함수의 호출은 컴파일 시기에 고정된 메모리 주소를 이용한다.

이러한 방식을 정적 바인딩(StaticBinding)이라고 말하는데, C++의 일반적인 멤버 함수는 모두 이러한 정적 바인딩을 사용한다.
다만 가상 함수는 프로그램이 실행될 때 객체를 결정한다는 점에서 컴파일 시간에 객체를 특정할 수 없다.

그래서 가상 함수는 실행 시간 때 올바른 함수가 실행될 수 있도록 동적 바인딩(Dynamic Binding)을 사용한다.

 

 

 

 

일반적인 함수의 정적 바인딩

 

코드 예시

#include <iostream>

using namespace std;

class A
{
public:
	void show() { cout << "A 클래스입니다." << endl; }
};
class B : public A
{
	void show() { cout << "B 클래스입니다." << endl; }
};
int main(void)
{
	A* p;
	A a;
	B b;
	p = &a; p->show();
	p = &b; p->show(); // 여전히 A 클래스의 show() 함수를 호출합니다.
	system("pause");
}

 

결과 값

 

가상 함수: 동적 바인딩 (virtual 명령어)

 

코드 예시

#include <iostream>

using namespace std;

class A
{
public:
virtual void show() { cout << "A 클래스입니다." << endl; }
};
class B : public A
{
virtual void show() { cout << "B 클래스입니다." << endl; }
};
int main(void)
{
A* p;
A a;
B b;
p = &a; p->show();
p = &b; p->show();
system("pause");
}

 

결과 값

 

'프로그래밍 > C++' 카테고리의 다른 글

#10 C++ 템플릿  (0) 2022.06.21
#9 다형성 기법 2  (0) 2022.06.20
#7 정적멤버,상수멤버  (0) 2022.06.18
#6 C++ 프렌드  (0) 2022.06.17
#5 C++ 오버로딩  (0) 2022.06.16
Comments