오늘은 Virtual 선언에 대한 이야를 합니다. 이 부분은 인터넷 검색을 하면 다양한 정의를 내리고 있는데 쉽게 어떤 하나의 틀 크래스가 정의 되었을 때 Virtual이라는 키워드로 정의한 함수는 나중에 파생 클래스에서 정의한 함수를 참조하여 재정의 할 수 있는 됩니다. 이 설명도 좀 어려울 수 있지만 예제를 보시면 쉽게 이해가 가실 거에요.
클래스 :
virtual 함수명(){
명령문1;
}
파생클래스
virtual 함수명(){
명령문2;
}
이렇게 선언 되었을 때 다음과 같이 접근을 합니다.
부모클래스 *op1 = new 부모클래스;
자식클래스 op2;
op1=&op2;
op1->함수명();
op1은 어떻게 될까요. 자식클래스의 함수가 실행되어 명령어2가 처리 됩니다. 여기서 혼동 하실 수 있는 부분은 상속 받은 자식 클래스에서 부모 클래스의 동일명 함수가 존재 할 때 해당 함수는 자식 클래스의 함수가 우선권으로 해당 함수를 호출 할때는 자식 클래스의 함수가 호출됩니다. 이것을 오버라이딩이라고 합니다. 약간 오버라이딩 같은 느낌으로 클래스를 생각 할 수 있겠지만 전혀 다릅니다. 부모 클래스는 그대로 유지하지하고 virtual로 선언된 함수만 재정의 됩니다. 이말은 기존 virtual로 선언되지 않는 일반 멤버함수는 동일한 이름이라도 변하지 않고 virtual로 선언된 함수만 재정의 된다는 점에서 오버라이딩과는 완전히 다릅니다. 그점만 기억해 주세요.
예)
class AAA {
public:
virtual output(){
cout<<"virtual AAA"<<endl;
}
};
class BBB : public AAA {
public:
virtual output(){
cout<<"virtual BBB"<<endl;
}
};
이렇게 선언을 시켜놓고 접근해 볼까요.
AAA *op1 = new AAA;
BBB op2;
op1=&op2;
op1->output();
이렇게 하면 결과는 이렇게 나옵니다
[결과]
코딩으로 설명하니 이해가 잘 안될 수 있으니 그림으로 정리해볼까요.
그러면 클래스 안에 virtual로 선언된 함수와 그렇지 않은 함수를 들어 비교하는게 이해하기 쉽겠죠.
실습 내용은 virtual로 선언된 함수와 일반 함수를 만들어서 그 결과가 어떻게 나오는지 비교함으로 virtual를 이해하자!
[전체소스]
#include
using namespace std;
class AAA {
public:
virtual output1(){
cout<<"virtual AAA"<<endl;
}
output2(){
cout<<"AAA"<<endl;
}
};
class BBB : public AAA {
public:
virtual output1(){
cout<<"virtual BBB"<<endl;
}
output2(){
cout<<"BBB"<<endl;
}
};
int main(int argc, char** argv) {
AAA *op1 = new AAA;
BBB op2;
op1=&op2;
op1->output1();
op1->output2();
return 0;
}
[결과]
virtual 선언은 사실 오버라이딩과 좀 햇갈릴 수 있습니다. 위 코딩에서 virtual과 일반함수 두가지 출력 결과를 보시고 구분하시기 바랍니다. 오버라이딩 같은 경우는 사실 BBB 클래스 자체가 오버라이딩 된 함수들입니다. AAA 클래스에 선언된 함수들이 BBB 클래스에 상속 시킬 때 동일명 함수들이 BBB 클래스에서 재정의 되었습니다. 이걸 오버라이딩이라고 합니다. 하지만 기존 클래스 틀에서 virtual로 선언된 해당 함수만 재정의 되기 때문에 둘은 다릅니다. 이 차이점을 구분하여 이해하시기 바랍니다. 나중에 오버로딩과 오버라이딩에 대해 이야기 하도록 할께요.