일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- 예외
- 티스토리챌린지
- more effective c++
- UE4
- resource management class
- exception
- 스마트 포인터
- 언리얼
- implicit conversion
- 게임
- reference
- 오블완
- virtual function
- Smart Pointer
- Effective c++
- 메타테이블
- 상속
- 암시적 변환
- 루아
- lua
- effective stl
- 영화
- 영화 리뷰
- 함수 객체
- operator new
- 반복자
- c++
- 참조자
- 다형성
- 비교 함수 객체
Archives
- Today
- Total
스토리텔링 개발자
[Effective C++] 36. 상속된 비가상 함수 이름 가리기 문제 본문
728x90
항목 36. 상속받은 비가상 함수를 파생클래스에서 재정의하는 것은 금물
비가상 함수를 가리면 생기는 문제
class B
{
public:
void mf();
...
};
class D : public B
{
public:
void mf(); // B::mf를 가려버린다!
...
};
D x; // D 타입
B* pB = &x; // x에 대한 포인터를 B*에 넣는다.
D* pD = &x; // x에 대한 포인터를 D*에 넣는다.
pB->mf(); // B::mf를 호출
pD->mf(); // D::mf를 호출!!!!
- 비가상 함수를 가려버리면, 포인터가 어디에 담겨있느냐에 따라 다르게 동작한다.
- 가상 함수 및 오버라이드를 사용했을 경우 발생하지 않는 문제이다.
문제 동작 이유
- 비가상 함수는 정적 바인딩으로 묶이기 때문이다. (항목 37 참조)
- pB는 'B에 대한 포인터' 타입으로 선언되었기 때문에, pB를 통해 호출되는 비가상 함수는 항상 B 클래스에 정의되어 있을 것이라고 결정해 버린다는 의미이다.
- 반면, 가상 함수는 동적 바인딩으로 묶인다. (항목 37 참조)
- 가상 테이블을 통해 올바른 클래스를 동적으로 찾아갈 수 있다.
- 그러므로 재정의를 해야 하는 상황이라면 반드시 가상 함수 오버라이드를 택하도록 하자.
가상 소멸자 문제
- 항목 7의 가상 소멸자 관련 문제는 사실 이번에 살펴본 문제의 특수한 경우라고 할 수 있다.
- 항목 5에서 봤듯, 컴파일러가 알아서 소멸자를 만들게 되면, 그야말로 비가상 함수를 가리는 상황이 되기 때문이다.
728x90
'개발 > Effective C++' 카테고리의 다른 글
[Effective C++] 38. 객체 합성 (0) | 2024.07.08 |
---|---|
[Effective C++] 37. 상속된 함수의 매개변수 기본값 재정의 문제 (0) | 2024.07.05 |
[Effective C++] 35. 일반 가상 함수 외의 구현법 (0) | 2024.07.04 |
[Effective C++] 34. 인터페이스 상속과 구현 상속의 차이 (0) | 2024.07.03 |
[Effective C++] 33. 상속된 이름 가리기 문제 (0) | 2024.07.02 |
Comments