C++ Virtual 키워드
by luis lee
Virtual 을 언제, 왜 사용해야하는가?
virtual function in Class
오버라이딩의 경우를 생각해보자.
class Parent{
...
};
class Child : public Parent{
...
}
다음과 같은 형식으로 class 가 구현되어있다고 해보자.
그런데 런타임에 어떤 클래스를 써야하는지 결정해야한다면 어떻게될까?
Parent * p;
Child * c;
if(childIsSelected){
//Child 를 선택한 경우는 Child 를 인스턴스화하고 함수실행.
c = new Child();
c->doFunction();
}
else{
//Parent 를 선택한 경우는 Parent 를 인스턴스화하고 함수실행.
p = new Parent();
p->doFunction();
}
이런식으로 두개를 모두 생성해놓고 사용하는건 굉장히 비효율적이고 코드상으로도 좋지 않다.
따라서 이러한 경우
Parent * p;
//Parent 포인터 하나만을 가지고 수행
if(childIsSelected){
p = new Child();
p->doFunction();
}
else{
p = new Parent();
p->doFunction();
}
Parent pointer 하나만 생성해놓고 사용할 수 있다. 즉 2개의 포인터를 관리하지 않고 하나만 가지고도 해결할 수 있는데 이때 virtual 이 사용된다.
class Parent{
...
virtual void doFunction(){...}
};
class Child : public Parent{
...
void doFunction(){...}
}
이런식으로 부모클래스에서 override 할 함수에 virtual 키워드를 붙이면 해결이 된다.
virtual 이라는 키워드는 컴파일러에게
“이 함수는 Parent 포인터에서 불렷지만 그게 아닐수도 있어!”
라는 정보를 준다. 따라서 실제 구동에서는 virtual function table 을 만들어서 virtual 함수가 호출된 경우에 table 을 확인해서 실제 어떤 오버라이드 함수를 실행해야하는지 결정하게한다.
따라서 virtual 은 어느정도의 오버헤드가 발생하게 된다. 자바계열에서는 모든 class member 함수가 virtual 함수라고 한다. c++ 에서는 키워드를 붙여야지만 virtual 이기 때문에 이를 잘 활용해보자.
주의할 점은 소멸자의 경우는 무조건 virtual 을 붙여야한다. 메모리 릭과 관련된 이슈가 발생할 수 있으므로 정확하게 오버라이드된 소멸자를 불러야하기 때문이다.
pure virtual function in Abstract class
virtual 키워드를 사용하는 약간은 다른 사용법은 추상 클래스에서다.
class Human{
...
virtual void walk() = 0;
};
class Child : public Human{
...
void walk(){...}
}
class Adult : public : Human{
...
void walk(){...}
}
여기서 Human 은 무조건 걸어야된다고 생각해보자. 그런데 나잇대에 따라서 걷는 속도, 걸음걸이, 보폭 등이 다르기 때문에 서로 다른 walk 함수를 반드시 오버라이드 시켜야한다고 하자.
즉, Human 은 무조건 걸어야되고, 각 나잇대별로 무조건 함수를 오버라이드 해야하는 상황이다.
Human h;
h.walk();
// Compile error
Human * h2 = new Child();
Human * h3 = new Adult();
순수 가상함수로 만들어진 Human 클래스는 생성이 안된다. 다만 포인터는 문제없이 만들 수 있다.
Human 클래스를 상속받는 클래스는 walk() 함수를 오버라이딩 해줘야만한다. (따라서 순사 가상함수는 반드시 public, protected 가 되야하며 private 으로 정의된 경우 오버라이드가 안된다)
이러한 Human 클래스를 추상 클래스라고 불리는데,
이를 사용해야하는 목적은 “설계도”의 기능입니다.
강제적으로 이 클래스의 하위 클래스는 미리 설계해 놓은 Human 클래스에서 사용할 순수 가상 함수를 직접 특수화해서 만들어야하는 것이다.
Subscribe via RSS