다형성이란 하나의 객체가 여러 가지 타입을 가질 수 있는 것을 의미한다. 즉, 겉으로는 같아 보이지만 기능은 다르게 동작하는 것이라 생각하면 된다.
C++에서 대표적인 다형성은 오버로딩과 오버라이딩, 그리고 템플릿등이 있다.
오버로딩
오버로딩은 함수의 중복 정의로써 단순히 함수 이름을 재사용하는것에 그친다.
class Player
{
void Move(){}
void Move(int speed){}//함수이름 재사용
};
오버라이딩
오버라이딩은 함수의 재정의로써 부모 클래스의 함수를 자식 클래스에서 다시 정의하는 것을 의미한다.
class Player
{
void Move(){cout<<"player"}
void Move(int speed){cout<<"player speed"}//함수이름 재사용
};
class Archor : public Player
{
void Move(){cout<<"Archor"}//함수 재정의
void Move(int speed){cout<<"Archor speed"}
};
상속관계에서의 다형성
상속관계에서는 부모클래스가 자식클래스의 대표할수 있게된다.
단, 반대의 경우는 성립하지 않는다.
class Player
{
void Move(){cout<<"Player";}
};
class Archor : public Player
{
void Move(){cout<<"Archor";}
};
void MovePlayer(Player* player)
{
player->Move();
}
void MoveArchor(Archor* archor)
{
Archor->Move();
}
int main()
{
Player p;
Archor a;
MovePlayer(&p)
MoveKnight(&p)//에러가 발생함
MovePlayer(&a)// 아처는 플레이어이기도 하므로 성립됨
MoveKnight(&a)
}
하지만 이 경우 MovePlayer(&a)의값은 Archor가 아닌 Player가 뜨게된다.
바인딩
위와 같이 정적바인딩을 사용할 경우 Archor의 참조를 받았지만 함수가 Player라는 포인터로 통합해서 관리할 경우 해당타입의 함수가 호출되게 된다. 따라서 이러한 것을 방지 및 유연하게 처리하기 위해서 동적바인딩을 이용한다.
정적 바인딩
일반함수에서 사용되며 컴파일 시점에 결정된다.
동적 바인딩
동적바인딩을 사용하기 위해선 가상함수(Virtual Function)를 사용해야된다. 동적바인딩은 실행 시점에서 결정되며 정적 바인딩보다 속도가 느리고 인라인함수도 사용할수 없지만 코드의 가독성과 편이성이 크게 증가되는 장점이있다.
class Player
{
virtual void VMove(){cout<<"Player";}
};
class Archor : public Player
{
void VMove(){cout<<"Archor";}
};
void MovePlayer(Player* player)
{
player->VMove();
}
void MoveArchor(Archor* archor)
{
Archor->VMove();
}
int main()
{
Player p;
Archor a;
MovePlayer(&a)// 결과 Archor가 출력됨
}
가상함수를 선언하면 가상함수 테이블이 만들어진다. 가상 함수 테이블이란 호출할 함수의 주소를 담는 함수 포인터 배열이다. 가상함수를 보유하면 가상함수 목록을 vftable로 작성하고 각 함수를 가리키는 vptr를 추가한다.
vftable은 생성자의 선처리 영역에서 만들어진다. 자식이 호출됫을 경우 먼저 부모클래스의 생성자에서 vftable에 vptr를 갱신하고, 다음으로 자식클래스의 생성자에서 vptr을 덮어써서 원하는 위치를 가르키도록 한다.
이런 가상함수 테이블 덕분에 상속관계에서의 자식이 부모로 나오는 것을 방지할수 있다.
순수 가상함수
가상함수의 구현이 존재하지 않고 틀만 제공하며 해당 클래스를 상속받은 자식클래스에게 구현을 맡기는 함수이다.
virtual void VF()=0; //순수 가상함수
추상클래스
순수 가상 함수가 1개 이상 포함되면 추상클래스로 간주하게된다. 이러한 추상 클래스는 직접적으로 객체를 만들수 없는 클래스가 된다.
템플릿은 매우 방대한 기법이므로 이 페이지에서 다루지 않겠다.
'C++복습' 카테고리의 다른 글
C++복습) Modern C++/ Auto (0) | 2021.12.22 |
---|---|
C++복습) 생성자 맴버 초기화 리스트 (0) | 2021.11.22 |
C++복습) 클래스 캡슐화(은닉성) (0) | 2021.11.20 |
C++복습) 클래스 상속성 (0) | 2021.11.20 |
C++ 복습) 클래스생성자와 소멸자 (0) | 2021.11.19 |
댓글