본문 바로가기
Object Oriented Programming(C++)/Effective C++

Effective C++ | 항목 37 어떤 함수에 대해서도 상속받은 디폴트 인수는 절대로 재정의하지 말자

by continue96 2024. 7. 26.

Effective C++ 항목 37

 

항목 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
ⓛ 디폴트 인수는 정적으로 바인드되고 가상 함수는 동적으로 바인드되기 때문에 상속받은 디폴트 인수는 절대로 재정의하면 안 된다.

댓글