Computer Security

#9 다형성 기법 2 본문

프로그래밍/C++

#9 다형성 기법 2

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

가상 함수
가상 함수(Virtual Function)란 자식 클래스에서 재정의할 수 있는 멤버 함수다.

virtual 키워드를 이용해 가상함수를 선언할 수 있으며 자식 클래스에서 가상 함수를 재정의하면 재정의된 멤버 함수 또한 가상 함수로 분류된다.

C++ 컴파일러는 가상 함수 테이블(Virtual Function Table)을 이용해 가상 함수를 다루게 된다.

C++ 컴파일러는 각각의 객체마다 가상 함수 테이블을 가리키는 포인터를 저장하기 위한 멤버를 하나씩 저장한다.
가상 함수 테이블에는 특정한 클래스의 객체들을 위해 선언된 가상 함수들의 주소가 저장된다.

따라서 가상 함수를 호출하면 C++ 프로그램은 가상 함수 테이블에 접근하여 자신이 필요한 함수의 주소를 찾아 호출하게 된다.
이러한 과정은 말 그대로 동적 바인딩을 통해 이루어지므로 컴퓨팅 리소스를 소모하게 된다.

그래서 C++은 기본적으로 정적 바인딩을 채택하고 있다.

따라서 자식 클래스가 재정의할 가능성이 있는 멤버 함수를 가상 함수로 선언하는 것이 좋다.

 

가상 클래스의 소멸자


C++에서는 상속 관계가 있으며 메모리 해제를 해야 하는 경우 반드시 부모 클래스의 소멸자를 가상 함수로 선언해야
한다.
만약 다형성을 이용할 때 소멸자를 가상 함수로 선언하지 않으면 자식 클래스의 소멸자는 호출되지 않고, 부모 클래
스의 소멸자만 호출되기 때문에 자식 클래스의 객체는 여전히 정상적으로 해제되지 않는다.

 

순수 가상 함수
C++의 가상 함수는 기본적으로 반드시 재정의할 필요는 없다.

하지만 순수 가상 함수(Pure Virtual Function)는 자식 클래스에서 반드시 재정의를 해주어야 하는 함수다.
그러므로 일반적으로 순수 가상 함수는 부모 클래스에서 함수 동작의 본체를 정의하지 않습니다. 자식 클래스에서 반
드시 이를 정의해야 사용할 수 있다.
순수 가상 함수는 ‘=0’ 키워드를 붙여서 선언할 수 있다.

 

코드 예시

#include <iostream>

using namespace std;

class A
{
public:
virtual void show()=0 { cout << "A 클래스입니다." << endl; }
};
class B : public A
{
// show() 함수를 재정의하지 않으면 B 클래스의 객체를 사용할 수 없습니다.
};

사용불가!

 

B클래스에서도 정의를 따로 해주어야 한다.(순수 가상함수이기 때문)

 

올바른 코드 예시

#include <iostream>

using namespace std;

class A
{
public:
	virtual void show() = 0 { cout << "A 클래스입니다." << endl; }
};
class B : public A
{
public:
	virtual void show() {cout << "B 클래스입니다." << endl;}
};

int main(void) {
	
	A* p;
	B b;
	p = &b; p->show();
	system("pause");
}

 

 

결과 값

추상 클래스


추상 클래스(Abstract Class)란 하나 이상의 순수 가상 함수를 포함하는 클래스를 의미한다.

추상 클래스를 활용하면 다형성을 효과적으로 프로그램 상에서 구현할 수 있다.
따라서 자식 클래스는 추상 클래스를 상속 받은 이후에 반드시 순수 가상 함수를 모두 오버라이딩 해야 비로소 해당
객체를 사용할 수 있다.

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

#11 C++ 스마트 포인터  (0) 2022.06.22
#10 C++ 템플릿  (0) 2022.06.21
#8 C++ 다형성 기법 1  (0) 2022.06.19
#7 정적멤버,상수멤버  (0) 2022.06.18
#6 C++ 프렌드  (0) 2022.06.17
Comments