공부/기타
C++ 가상함수 (Virtual Function)
로디네로
2021. 7. 23. 00:38
반응형
가상함수 :
- 기본 클래스 내에서 선언되어 파생클래스에 의해 재정의되는 멤버함수이다.
- virtual 를 함수앞에 붙여서 생성할 수 있다.
- 파생 클래스에서 재정의하면 새롭게 정의된 내용들로 교체된다.
사용하는 이유 :
일반 함수를 오버로딩하게 되면 정적바인딩으로 문제가 생길 수 있기 때문이다.
ex)
class Animal{
public:
void eat() {cout << "A" << endl;}
};
class Cat:public Animal{
public:
void eat() {cout << "B" << endl;} //기본클래스의 함수를 덮어쓰려 합니다.
};
int main(){
Animal *pAnimal;
Cat cat;
pAnimal = &cat;
pAnimal->eat(); // "A"
return 0;
}
//출처 : https://hjjjong0811.github.io/2018/09/13/programming/180913_CPP%EA%B0%80%EC%83%81%ED%95%A8%EC%88%98/?
Cat에 있는 eat 함수를 호출하려 했으나, Animal의 eat 함수가 호출된다.
- 포인터의 주소를 바꿔줬음에도 정적바인딩으로 인해 호출될 함수의 번지가 이미 결정되었기 때문에 부모(Animal)의 함수가 호출 되는 것이다.
- 정적바인딩이 아닌 동적바인딩을 해야 한다.
-> 일반함수들을 가상함수로 바꾸어 주면 된다.
(포인터의 타입이 아닌 포인터가 가리키는 객체의 타입에 따라 멤버함수를 선택하게 된다.)
가상함수 적용 :
#include <iostream>
using namespace std;
class Parent{
public:
virtual void v_print() { //virtual함수 선언
cout << "A" << endl;
}
};
class Child : public Parent{
public:
virtual void v_print() {
cout << "B" << endl;
}
};
void main() {
Parent* p = new Parent;
Child* c = new Child;
p->v_print();
p = c;
p->v_print();
}
//출처 : https://coding-factory.tistory.com/699
출력 : A B |
부모의 print() 함수를 virtual 함수로 선언, 동적바인딩을 해서 문제를 해결할 수 있다.
반응형