예를 들어, 아래의 코드에서는 child의 call method가 호출된다.
### c++
class parent {
public:
virtual void call();
};
class child : public parent {
public:
void call();
};
int main()
{
parent* p = new child;
p->call(); // child의 call이 호출됨
}
그렇다면 child의 instance는 virtual로 선언된 메소드들에 대해서 항상 child를 호출하는가?
오늘 그렇지 않다는 것을 배웠다.
아래 예제를 보자.
### c++
#include <stdio.h>
static void externalCall();
class A
{
public:
A() {
printf("In Constructor A\n");
call();
}
virtual ~A() {
printf("In Destructor A\n");
call();
externalCall();
}
virtual void call() {
printf(" Call A is called\n");
}
void callFromA() {
printf(" > In %s \n", __func__);
call();
}
};
class B : public A
{
public:
B() {
printf("In Constructor B\n");
call();
}
~B() {
printf("In Destructor B\n");
call();
externalCall();
}
void call() {
printf(" Call B is called\n");
}
};
static A* global;
static void externalCall()
{
printf(" > In %s \n", __func__);
global->call();
}
int main()
{
A* local = new B;
printf("In %s \n", __func__);
local->call();
local->callFromA();
global = local;
externalCall();
delete local;
}
위 예제를 실행해보면 재밌는 결과를 얻을 수 있다.
In Constructor A ---- 1 |
1. 실행 결과에서 먼저 생성자의 호출 순서를 알 수 있다.
생성자의 경우 부모클래스(A)의 생성자가 호출된 후, 자식 클래스(B)의 생성자가 호출된다.
이 때, 자식 클래스의 생성자가 호출되기 이전에 부른 call method는 부모 클래스의 method가 호출됨을 알 수 있다.
2. main에서는 예측한 것과 같이 자식 클래스(B)의 method만이 호출됨을 알 수 있다.
설령, 부모클래스의 메소드를 거쳐서 호출하더라도(callFromA) 자식 클래스의 인스턴스이기 때문에 자식 클래스의 메소드가 호출된다.
3. destructor의 호출 순서는 생성자의 경우와 반대로 자식 클래스의 소멸자 -> 부모클래스의 소멸자 순으로 불린다.
이 때, 자식 클래스의 소멸자 안에서 호출한 call method는 자식 클래스(B)의 메소드가 불린 반면,
부모 클래스(A)의 소멸자 안에서는 자식 클래스(B)의 call method가 아닌, 부모 클래스(A)의 call method가 불린 것을 알 수 있다.
externalCall의 결과만 보면 자식 클래스(B)의 소멸자에서 불릴때와 부모클래스(A)의 소멸자에서 불릴때 다른 메소드가 불리게 된다는 것을 알 수 있다.
소멸자가 부른 외부 함수(또는 다른 클래스의 함수)가 이를 모르고 호출할 경우, 의도하지 않은 동작을 할 수도 있기 때문에,
소멸자가 호출하는 함수가 다시 자신의 메소드를 호출하지 않도록 주의할 필요가 있을 것 같다.
PS>
쓰고 보니 이미 Effective C++에서 다루고 있는 내용이었다.
다시 읽어봐야겠다. ㅠ_ㅠ
'프로그래밍 언어 > C&C++' 카테고리의 다른 글
[C++11] Type Inference: auto (4) | 2013.11.01 |
---|---|
c++11 스터디(목차) (0) | 2013.11.01 |
GCC 옵션 : version script (0) | 2012.08.14 |
[C++] new는 null을 return하는가? (1) | 2012.01.17 |
static const char* vs static const char [] (0) | 2012.01.04 |