프로그래밍/C++

#42. 다형성 virtual

코딩하는상후니 2022. 7. 19. 22:15

 

*virtual 로 선언된 함수를 자식에서 재정의했을때
자식클래스 vptr은 부모인가?자식에있는 함수인가??
=> 당연히 자식에 있는 함수 포인터로 저장됨.
=> 마지막으로 재정의된 함수포인터를 가지고 있음.
 
 
*부모클래스 선언시 vptr 이 생기나??
=> 반드시 생김.
virtual 함수가 존재하면 객체 생성 시,
생성자 이전 '선처리 영역' 에서 vftable offset 저장.
 
=> 각 객체마다 독립적인 vfptr 을 가지고 있음.
 
 

 

*다형성 ( Polymorphism )
 
*오버로딩
=> 함수의 이름을 재사용
 
*오버라이딩
=> 함수를 재정의

 

 

 

*정적 바인딩 ( Static Binding )  :  컴파일 시점에 결정
=> 일반적인 함수
 
* 동적 바인딩 ( Dynamic Binding )  :  실행 시점에 결정
=> virtual function  (  가상함수  )
=> 런타임 시, 실제 객체가 어떤 타입인지 찾고 실행.
=> 가상함수는 재정의를 하더라도 가상함수다 !!
즉, 자식의 virtual / override 을 붙여주지 않아도 동작함. ( 표시용도 )
하지만, 되도록 붙여주는 것이 좋음.
 
vftable
=> 해당 주소를 찾는데 시간이 걸리지만 엄청난 부하는 아님.
그렇다고 모든 함수를 가상함수로 만들 필요도 없음.
 
 

 

 


 

 

*가상함수 동작 원리
class Player
{
public:
	Player();

public:
	virtual void Move();
	virtual void Move(int a);

	void Test();
}

Player& P1 = F1;
P1.Move();

P1.Move(10);

 

=> 만약 가상함수가 정의되어있다면, 객체는 vftable  을 가지고 있다.
=> 만약 자식 클래스에 가상함수가 재정의 되어있지 않다면
최상위 클래스의 vptr 을 가지고 있다.
 
1.
mov eax, dword ptr  [P1]
mov edx, dword ptr [eax]
=> 가상함수 가 실행되면, vptr 에 접근.
=> 객체 첫 주소는 vptr
 
2.
eax, dword ptr [edx+4]
=> 몇번째 가상함수 인지 찾음.
 
 
3. 가상함수 실행
 
 
*어느 시점에 vftable 을 채워주나 ??
=> 생성자 '선처리 영역' 에서
mov, dword ptr [eax],offset FireAcher::`vftable' (0389BF0h) => (Player vftable)

 


 

 

@최상위 객체의 소멸자 virtual
=>
상속 관계에서,
자식 클래스가 부모클래스의 참조로 있을 때, 실제 원본 객체의 소멸자를 호출하기 위함.
 
즉, virtual 을 붙임으로써 vftable 포인터를 가지면서 원본 객체의 소멸자를 호출 가능.
소멸자에 virtual 하나만 붙어있어도 vptr 을 가지나?? => 그렇다.
 
 
*그렇다면 실제 원본 객체의 소멸자를 호출 후,
부모클래스의 소멸자는 어떻게 호출될까??

=> 컴파일러가 해당 원본 객체 '소멸자 호출 이후의 영역' 에서
해당 부모의 소멸자를 호출하는 것을 볼 수 있음.
 
즉, 우리가 따로 자식 소멸자에서 부모 소멸자를 호출하지 않아도 된다는 의미.
하지만, 최상위 부모 소멸자에 virtual 을 붙여주어야 함.
 

 

*순수 가상 함수
=> 구현은 없고 '인터페이스' 만 전달하는 용도
=> 상속하는 부분에서 무조건 정의해주어야함.
=> 함수이름과 함수기능을 강제함.
 
 
*추상클래스
=> '순수 가상 함수' 가 하나라도 존재하는 클래스
=> 직접적으로 객체로 생성될 수 없음.
 
 

 


 

 

*업캐스팅
=> 자식이 상위 부모 객체로 넣어지는 형변환
 
 
*다운캐스팅
=> 부모에서 자식으로 갈 때, 해당 객체로 정말 형변환할 수 있는지 확인해야함.
=> dynamic_cast
 

 

 

본 내용은 인프런의 루키스님 강의를 듣고 정리한 내용입니다.

'프로그래밍 > C++' 카테고리의 다른 글

#44. 연산자 오버로딩  (0) 2022.07.20
#43. 초기화 리스트  (0) 2022.07.20
#41. 은닉성  (0) 2022.07.19
#40. 상속성  (0) 2022.07.19
#39. 생성자 & 소멸자  (0) 2022.07.19