지금까지 다른 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로 고정할 수 있다.
이것만은 잊지 말자!
상속받은 기본 매개변수값은 절대로 재정의해서는 안된다. 왜냐면 기본매개변수는 정적바인딩 되는 반면, 가상함수는 동적바인딩 되기때문이다.
'책 정리 > Effective C++ 3rd' 카테고리의 다른 글
항목 39. private 상속은 심사숙고해서 구사하자 (0) | 2020.03.16 |
---|---|
항목 38. "has-a(…는 …를 가짐)" 혹은 "is-implemented-in-terms-of(…는…를 써서 구현됨)"를 모형화할 때는 객체 합성을 사용하자 (0) | 2020.03.12 |
항목 36. 상속받은 비가상 함수를 파생 클래스에서 재정의하는 것은 절대 금물! (0) | 2020.03.10 |
항목 35. 가상 함수 대신 쓸 것들도 생각해 두는 자세를 시시때때로 길러 두자 (0) | 2020.03.10 |
항목 34. 인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구별하자 (0) | 2020.03.09 |
댓글