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

항목 37. 어떤 함수에 대해서도 상속받은 기본 매개변수 값은 절대로 정의하지 말자

by ocean20 2020. 3. 10.

지금까지 다른 c++책을 보면 다형성에 대해 배웠던 적이 있을텐데(가상함수 바인딩), 여기서 설명할 것은 "기본 매개변수 값이 설정된" 가상함수 바인딩하게 되면 뭔가 꼬이기 시작한다.

 

class Shape{
public :
  enum ShapeColor { Red, Green, Blud };
  virtual void draw(ShapeColor color = Red) const = 0;
};

class Rectangle : public Shape {
public :
  virtual void draw(ShapeColor color = green) const;
};

class Circle : public Shape{
public :
  virtual void draw(ShapeColor color) const;
};

Shape *ps;
Shape *pc = new Circle;
Shape *pr = new Rectangle;

 

여기서 ps, pc, pr 정적타입 가리키든 "호출객체의 타입"인 Shape이다.

동적타입 "가리키고 있는 대상의 타입"을 뜻한다.

 

어쨌든, pr->draw(); 코드 결과로는 Rectangle::draw(Shape::Red) 호출된다.. (Shape::Green) 아니라..

 

이유는 Shape 클래스에서 기본 매개변수값이 Red 설정되어 있기때문에,

Rectangle에서 재정의한 가상함수 draw() 매개변수가 기본클래스인 Shape Shape::Red 고정된다는 것이다.


이를 해결하기 위해서는.. 지난 항목 36에서 배운 Non Virtual Interface(NVI) 사용하여 해결해보는 것이다.

class Shape{
public :
  enum ShapeColor { Red, Greeen, Blue };
  void draw(ShapeColor color = Red) const        // 비가상함수 Red 고정
  {   
    doDraw(color); // private한 가상함수를 호출
  }
private :
  virtual void doDraw(ShapeColor color) const = 0;
};

class Rectangle: public Shape {
public :
  …
private :
  virtual void doDraw(ShapeColor color) const;  // 가상함수 재정의, 실질적인 작업이 여기서 이루어짐
};

 

위와 같이 설계시, draw 함수의 color 매개변수에 대한 기본값을 깔끔하게 Red 고정할 있다.

 


이것만은 잊지 말자!

상속받은 기본 매개변수값은 절대로 재정의해서는 안된다. 왜냐면 기본매개변수는 정적바인딩 되는 반면, 가상함수는 동적바인딩 되기때문이다.

댓글