Skip to content

Latest commit

 

History

History
32 lines (28 loc) · 1.58 KB

Item36.md

File metadata and controls

32 lines (28 loc) · 1.58 KB

항목 36. 상속받은 비가상 함수를 파생 클래스에서 재정의하는 것은 절대 금물!

비가상 함수의 상속과 재구현

class B{
public:
    void callFunc(); // 비가상 함수
};

class D : public B{
public:
    void callFunc(); // B::callFunc를 가린다
}

D x;
B * pb = &x;
D * pd = &x;

pb->callFunc(); // B::callFunc()를 호출한다.
pd->callFunc(); // D::callFunc()를 호출한다.
  • 비가상 함수 callFunc를 파생 클래스에서 재정의 한다면 함수도 똑같고 객체도 똑같으나 실제로 호출이 다른 문제가 발생한다.
  • public 상속에서 is-a 관계에 모순이 발생한다.
  • DB의 일종이고 callFunc가 클래스 상속과는 상관없는 B불변동작에 해당한다면 D에서는 callFunc를 재정의할 생각을 하면 안된다.

다른 호출이 발생하는 이유

  • 비가상 함수는 정적 바인딩으로 묶인다.
    • pbB에 대한 포인터타입으로 선언되었다.
    • pb를 통해 호출되는 비가상 함수는 항상 B 클래스에 정의되어 있을 것이라고 결정해 버린다.
    • B, D를 좌우하는 요인이 객체 자신이 아니라 객체를 가리키는 포인터의 타입이 된다.
  • 가상 함수는 동적 바인딩으로 묶인다.
    • callFunc 함수가 가상 함수였다면 callFuncpb에서 호출되든 pd에서 호출되든 D::mf가 호출된다.
    • pb, pd가 실제로 가리키는 대상은 D 타입의 객체이기 때문이다.