본문 바로가기
책 정리/Effective C++ 3rd

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

by ocean20 2020. 3. 10.

1. 바인딩 :  프로그램 소스에 쓰인 각종 내부 요소, 이름, 식별자들에 대해 혹은 속성을 확정하는 과정을 일컫는다.

빌드중에 이과정이 일어나면 정적바인딩, 실행중에 일어나면 동적바인딩

c++에서 가상함수 바인딩은 문서상으로 동적바인딩이나, 실제로는 런타임 성능을 높익기 위해 정적 바인딩을 쓴다.

컴파일 중에 가상함수테이블을 파생 클래스에 맞게 바꿈으로서 정적바인딩처럼!

ex) "int foo = 2;" 일때 데이터타입이 int인것과 변수명이 foo 정해지는게 정적바인딩이고 foo 변수에 2가대입되는게 동적바인딩이다!

 

lass B{
public :
  void mf(); // 비가상함수
};

class D : public B{
public :
  void mf(); //비가상함수 재정의
};
B *pB = new D();
D *pD = new D();
pB->mf();  // B::mf()가 호출
pD->mf(); // D::mf()가 호출

 

비가상함수를 위와 같이 호출시 호출한 객체의 타입으로 묶인 mf() 호출된다.

가상함수 호출시 호출객체가 가리키는 타입의 mf() 호출된다.

 

2. 비가상함수를 파생클래스에서 재정의하면 안되는 이유

  1) D B 일종이다라는 명제(public 상속) 참이라는 가정하에, D mf() B 다르게 구현하고싶어하고, B포함 B파생클래스로부터 만들어진객체가 B mf() 사용해야한다고 가정한다면, D is B 명제가 거짓이되므로 모순이다. 이때는 public 상속금지이다.

 

  2) D B로부터 상속받을수밖에 없는 이장이라면, 그리고 D에서 B 다르게 구현해야한다면, "mf 클래스 파생에 상관없이 B 불변동작을 나타낸다"라는 명제가 거짓이된다. 이때는 가상함수사용필요하다.

 

  3) 만약 모든 D B 일종이고 mf B 대해 불변동작을 보여야한다면, 재정의 자체를 생각하는게 문제다.

 

이것만은 알아두자!

상속받은 비가상함수를 재정의 하지 말자!

댓글