본문 바로가기
!?/C++

클래스 가상함수

by Where's my namespace 2012. 8. 30.

클래스에는 가상함수(virtual) 이라는 개념이 있다. 

어떤것인지 살펴보자.

 

우선 가상함수를 사용하는 방법 먼저 살펴보자.

 

특별한 것은 없고, 일반적인 부모클래스 멤버 함수 앞에.

 

virtual void print();

 

등과 같이 virtual 만 붙여주면 된다.  클래스 외부에서 함수 내용을 정의 할 때는 클래스 내부에 함수 원형에만 virtual 을

붙여주면 된다.

 

자, 이제 이 가상함수를 어떤 경우에 쓰는지 살펴보자. 한가지 예로 shape 클래스와, circle, rect 클래스 먼저 간단히 정의 먼저 보자.

 

class shape {

public :

void draw() const;

protected :

int _x, _y;

}

 

class circle : public shape

{

public :

void draw() const;

}

 

class rect : public shape

{

public :

void draw() const;

}

 

위와 같은 클래스들이 있다고 생각해보자(안에 생성자, 소멸자 변수도 있어야하지만 생략) , 

도형 클래스에 원, 사각형 클래스가 자식으로 있는 상황이다.

위에서 보면 각자의 draw 함수를 가지고 있다. 각자 출력하는게 다르기 때문에 각자 함수를 가지고 있다. 

 

그리고 메인 내부에서는

 

shape* arr[5] = {NULL};

arr[0] = new circle;

arr[1] = new rect;

 

와 같이 선언 되어있다.  그리고서 

 

for( int i = 0 ;   i < 5 ; i++ )

arr[i]->draw();

 

라고 한다면 어떤 draw 가 호출될까? 

 

 이렇게 되면 처음 의도한 각 도형마다 다르게 출력되는 방식이 아니라, shape 클래스의 draw 함수가 호출된다.

 

이런 경우에 우린 virtual 함수를 쓸 수 있다. 위의 예제에서 간단히 부모 클래스를 다음과 같이 고치면된다.

 

class shape {

public :

virtual void draw() const;

protected :

int _x, _y;

}

 

이렇게 고쳐주면 위의 예제

 

for( int i = 0 ; i < 5 ; i++ )

arr[i]->draw();

 

를 호출 했을때 각자 가지고 있는 draw함수를 호출 하게 된다. 가상함수를 쓰면 이렇게 편하다. 단순히 virtual 코드만 써

줬는데도 엄청 편리해졌다. 여기서 보면 단순히 부모 클래스에만 virtual 를 써줬는데, 부모클래스에만 써주면 자식클래스

는 자연스럽게 가상함수가 된다. 하지만 일반적으로는 자식클래스에도 써주는게 소스를 보기에 좋다.

 

그리고 중요한것은 클래스 내에 하나 이상의 가상함수가 존재한다면 소멸자도 가상함수를 써줘야한다. 단순히 앞

에 virtual 만 붙여 주면 된다.

 

 

내용과는 크게 관련없지만, 바인딩에 대해 알아보자.

 

바인딩은, 함수를 호출하는 명령과, 실제 호출되는 함수를 서로 짝지어 주는 것을 말한다.

 

바인딩은 동적 바인딩 과,  정적 바인딩이 있다.  우선 동적 바인딩을 보면 위의 예제가 딱 동적 바인딩이다.

 

for( int i = 0 ; i < 5 ; i++ )

arr[i]->draw();

 

위의 경우에 프로그램이 실행하기 전에 어떤 함수가 호출되는지 알수없다. 이것이 동적 바인딩이다.

이 반대의 경우, 봤을때 어떤 함수가 호출될지가 분명한 것이 정적 바인딩이다.

 

'!? > C++' 카테고리의 다른 글

Exception Handling  (0) 2012.09.10
오버라이딩  (0) 2012.08.30
클래스 상속과 포함.  (0) 2012.08.28
클래스 2  (0) 2012.08.19
클래스 1  (0) 2012.08.16