책 정리/Effective C++ 3rd
항목 37. 어떤 함수에 대해서도 상속받은 기본 매개변수 값은 절대로 정의하지 말자
ocean20
2020. 3. 10. 15:36
지금까지 다른 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로 고정할 수 있다.
이것만은 잊지 말자!
상속받은 기본 매개변수값은 절대로 재정의해서는 안된다. 왜냐면 기본매개변수는 정적바인딩 되는 반면, 가상함수는 동적바인딩 되기때문이다.