[ Programming ]2009. 7. 15. 13:51
상속이란 개념을 두가지로 나누면 함수 인터페이스의 상속, 함수 구현의 상속이 있음.
클래스 설계 입장에서는 멤버 함수의 인터페이스(선언)만을 파생 클래스에 상속받고 싶을때, 또는 함수의 인터페이스 및 구현을 모두 상속 받고  그 상속 받은 구현이 오버라이드가 되게, 마지막으로 인터페이스와 구현을 상속받되 어떤 것도 오버라이드 할수 없게 할 없도록 하고 싶을때가 있음. 눈치 빠르신 분들은 아마도 다 아실것 같은데.. virtual에 관한 이야기 입니다.
순수 가상 함수인가? 가상함수인가? 비가상함수인가? 를 구분지어서 사용하기 입니다.

  1. 순수가상함수 : 어떤 순수 가상 함수를 물려 받은 구체 클래스가 해당 순수 가항 함수를 다시 선언 해야 함.
                         순수 가상 함수는 전형적으로 추상 클래스 안에서 정의를 갖지 않는다.(정의를 갖지고 있을 수도 있음)                            즉, 순수가상함수는 파생 클래스에게 함수의 인터페잇만을 물려 주는 것.

  2. 단순(비순수)가상함수 : 순수가상함수 처럼 인터페이스를 상속하게 한다는 점은 같고, 파생 클래스 쪽에서 오버라이드
                                    할 수 있는 함수 구현부도 제공한다는 점.
                                    즉, 인터페이스뿐만 아니라, 그 함수의 기본 구현도 물려 주는 것.

  3. 비가상 함수 : 인터페이스와 더불어 그 함수의 필수적인 구현을 물려 주는 것. 불변동작(파생 클래스에서 재 정의 하면                          안됨.                                                                                                                                     

단순 가상 함수에서 함수 인터페이스와 기본 구현을 한꺼번에 지정하도록 내버려 두면 위험 할수도 있음.

class AirPort
{
	/// 공항을 나타내는 클래스.
};

class Airplane
{
	virtual void fly(const AirPort& destination)
	{
		/// 기본 구현 코드.
	}
};

class ModelA : public Airplane
{
	/// ModelA는 기본 fly 함수를 사용.
};

class ModelB : public Airplane
{
	/// ModelB는 기본 fly 함수를 사용.
};

/*
	ModelA, ModleB는 fly 기본 구현을 사용하는데 나중에 만들어진 ModelC에서는 
    전혀 다른 fly를 사용할 때 fly를 재정의 하지 않고 기본 fly를 사용하는 실수를 
    할수 있는데 이런 실수를 방지 하기 위해서 가상 함수의 인터페이스와 
    그 가상 함수의 기본 구현을 잇는 연결 관계를 끊어 버리는 것.
*/
class Airplane
{
public:
	/// fly를 순수 가상함수로 만듬.
	virtual void fly(const AirPort& destination) = 0;
protected:
	void defaultFly(const AirPort& destination)
	{
		/// ModelA와 ModelB에서 사용할 기본 fly 함수를 비가상 함수르 정의.
	}
};
/*
	fly를 순수 가상 함수로 만들어 반드시 재정의 하도록 만들어서 위에서 할수 있는 실수를 방지.
*/
class ModelA : public Airplane
{
public:
	virtual void fly(const AirPort& destination)
	{
		/// ModelA는 defaultFly를 사용.
		defaultFly(destination);
	}
};
class ModelB : public Airplane
{
public:
	virtual void fly(const AirPort& destination)
	{
		/// ModelB는 defaultFly를 사용.
		defaultFly(destination);
	}
};
class ModelC : public Airplane
{
public:
	virtual void fly(const AirPort& destination)
	{
		/// ModelC만의 fly를 구현한다.
	}
};
/*
	위와 같은 내용이지만 순수 가상 함수에 구현을 하고 그것을 호출 하는 방법.
*/
class Airplane
{
public:
	/// fly를 순수 가상함수로 만듬.
	virtual void fly(const AirPort& destination) = 0;
};
void Airplane::fly(const AirPort &destination)
{
	/// ModelA와 ModelB에서 사용할 기본 fly 함수를 구현.
}
class ModelA : public Airplane
{
public:
	virtual void fly(const AirPort& destination)
	{
		/// 다음과 같이 사용.
		Airplane::fly(destination);
	}
};
Posted by 냉동