항목 37 어떤 함수에 대해서도 상속받은 디폴트 인수를 재정의하지 말자
37.1 정적 바인딩과 동적 바인딩
- 가상 함수는 동적 바인딩(dynamic bind)된다.
- 가상 함수는 호출한 객체의 동적 타입(dynamic type)에 따라 어떤 함수를 호출할지 결정된다.
- 객체의 동적 타입이란, 현재 그 객체가 무엇인지에 따라 결정되는 타입을 말한다.
- 디폴트 인수는 정적 바인딩(static bind)된다.
- 디폴트 인수는 객체의 정적 타입(static type)에 따라 어떤 디폴트 인수를 사용할지 결정된다.
- 객체의 정적 타입이란, 객체를 선언할 때 결정되는 타입을 말한다.
class Shape
{
public:
enum ShapeColor { RED, GREEN };
virtual void Draw(ShapeColor shapeColor = RED) const = 0;
};
class Rectangle : public Shape
{
public:
virtual void Draw(ShapeColor shapeColor = GREEN) const;
};
class Circle : public Shape
{
public:
virtual void Draw(ShapeColor shapeColor) const;
};
Shape* pRectangle = new Rectangle;
pRectangle->Draw();// 정적 타입이 Shape*이므로 디폴트 인수로 GREEN이 아닌 RED가 전달됩니다.
Shape* pCircle = new Circle;
pCircle->Draw();// 디폴트 인수로 RED가 전달됩니다.
37.2 비가상 인터페이스 관용구
- 기본 클래스와 파생 클래스에 있는 디폴트 인수를 통일하는 데 비가상 인터페이스(NVI) 관용구를 사용할 수 있다.
- 파생 클래스에서 재정의할 수 있는 private 가상 함수를 선언하고 이 가상 함수를 호출하는 public 비가상 함수를 기본 클래스에 선언한다.
class Shape
{
public:
enum ShapeColor { RED, GREEN };
void Draw(ShapeColor shapeColor = RED) const { DoDraw(color); }
private:
virtual void DoDraw(ShapeColor shapeColor) const = 0;
};
class Rectangle : public Shape
{
public:
virtual void DoDraw(ShapeColor shapeColor) const;
};
NOTE
ⓛ 디폴트 인수는 정적으로 바인드되고 가상 함수는 동적으로 바인드되기 때문에 상속받은 디폴트 인수는 절대로 재정의하면 안 된다.
'Object Oriented Programming(C++) > Effective C++' 카테고리의 다른 글
Effective C++ | 항목 39 private 상속은 심사숙고해서 구사하자 (0) | 2024.08.06 |
---|---|
Effective C++ | 항목 38 has-a 혹은 is-implemented-in-terms-of를 모형화할 때는 객체 합성을 사용하자 (0) | 2024.08.06 |
Effective C++ | 항목 36 상속받은 비가상 함수를 자식 클래스에서 재정의하는 것은 절대 금물! (0) | 2023.05.21 |
Effective C++ | 항목 34 인터페이스 상속과 구현 상속의 차이를 제대로 파악하고 구분하자 (0) | 2023.05.21 |
Effective C++ | 항목 33 상속된 이름을 숨기는 일은 피하자 (0) | 2023.05.20 |
댓글