[Effective C++] #37 가상 함수, 기본 매개변수
Scott Meyers의 "Effective C++"를 통해, C++ 구현에 필요한 개념들을 이해하고, 기록하기 위함입니다. 해당 항목은 6장 "상속, 그리고 객체 지향 설계", 항목 37 "어떤 함수에 대해서도 상속받은 기본 매개변수 값은 절대로 재정의하지 말자"에 해당하는 내용입니다.
가상 함수, 동적 바인딩
class Shape
{
public:
virtual void Draw(ShapeColor color = Red) const = 0;
enum ShapeColor { Red, Blue, Green };
...
};
class Rectangle : public Shape
{
virtual void Draw(ShapeColor color = Green) const;
...
};
Shape* p1; // 정적 타입 = Shape*
Shape* p2 = new Rectangle; // 정적 타입 = Shape*, 동적 타입 = Rectangle*
p2->Draw(); // Shape::Red, 기본 클래스의 기본 매개변수가 사용됩니다!
먼저, 이전 항목에서 살펴본 가상 함수의 "바인딩"에 대한 개념을 되짚어 보겠습니다. 자세한 내용은 아래 링크를 참고해 주세요. 가상 함수는 "동적 바인딩"되며, 프로그램 실행 중에 속성이 확정됩니다. 반면에, "기본 매개변수"가 설정된 가상 함수의 경우 문제가 발생합니다, 왜냐하면 기본 매개 변수는 정적으로 바인딩되기 때문입니다. 이번 항목에서는 이러한 문제 발생을 방지하는 설계 기법을 알아보겠습니다. 앞서 공부했던 NVI(비 가상 인터페이스) 설계 패턴입니다. 자세한 내용은 아래 링크를 참고해주세요.
NVI, 기본 매개 변수 재정의 방지
class Shape
{
public:
enum ShapeColor { Red, Green, Blue };
void Draw (ShapeColor color = Red) const
{
doDraw(color);
}
private:
virtual void doDraw(Shapecolor color) const = 0;
...
};
class Rectangle
{
public:
...
private:
virtual void doDraw(Shapecolor color) const = 0; // 기본 매개변수 값이 없다.
...
};
NVI 방법은 파생 클래스에서 재정의 가능한 가상 함수를 private 영역에 두고, 이 가상 함수를 본문에 호출하는 비 가상 함수를 public 영역에 두는 것입니다. 비 가상 함수의 경우, 파생 클래스에서 재정의를 제한하므로, 기본 매개변수의 값이 변경되지 않습니다. 따라서, 선행 바인딩(=정적 바인딩)된 기본 매개변수 값 또한 파생 클래스에서 재정의 할 수 없게됩니다.
'언어 > Effective C++' 카테고리의 다른 글
[Effective C++] #39 private 상속 (0) | 2022.02.16 |
---|---|
[Effective C++] #38 객체 합성, private 영역, "has-a" ,"is-implemented-in-terms-of" (0) | 2022.02.09 |
[Effective C++] #36 비 가상 함수의 상속, 바인딩 (0) | 2022.02.04 |
[Effective C++] #35 Public 가상 함수의 대안, NVI, 전략 패턴 (0) | 2022.02.03 |
[Effective C++] #34 사용자 정의 기본 멤버 함수 (0) | 2022.01.31 |