13. C++ 코드 재활용(1) - private 상속

WanJu Kim·2022년 12월 15일
0

C++

목록 보기
55/81

C++가 추구하는 목표 중 하나가 코드의 재활용이었는데, 지금까지 우리는 이를 상속을 통해서 실현했다. 이번에는 다른 방법들을 알아보겠다.

첫 번째 방법은 클래스 객체 안에 클래스 객체를 쓰는 건데, 교재에선 valarray 클래스를 사용했다. 난 처음 보는데 뭔가 vector가 더 좋은 것 같아서 이건 넘어가고... 여기서 컨테인먼트(containment)라는 용어만 알고 가자. 그냥 말 그대로 클래스에 다른 클래스의 객체를 포함시키는 게 컨테인먼트다.

두 번째 방법은 private 상속이다. private 상속에서는, 기초 클래스의 public 멤버와 protected 메서드가 파생 클래스의 public 멤버가 된다. public 상속을 상기시키면, 기초 클래스의 public 메서드가 파생 클래스의 public 메서드가 됐었다.

컨테인먼트랑 private 상속이랑 차이는, 컨테인먼트는 이름이 있는 객체 형태로 클래스에 추가하고, private 상속은 그렇지 않다는 것이다. 그렇지만 이 둘은 동일한 기능을 제공한다.

근데 주 기능은 데이터를 더 보호하고 싶다는 건가? 파생 클래스 객체로 기초 클래스 멤버들은 사용 못 하니 말이다.

예시를 하나 보겠다.

class Student : private std::string, private std::valarray<double>
{
	public:
    ...
};

두 개 이상 상속 받을 때는 이렇게 쓴다. 그리고 이걸 다중 상속이라 부른다. 일반적으로 이렇게 쓰면 문제가 생긴다는데, 지금은 그렇지 않다.

컨테인먼트와 private 상속의 차이는 어떤 게 있을까?

// 컨테인먼트의 경우.
double Student::Average() const
{
	if (scores.size() > 0)
    	return scores.sum() / scores.size();
	else
    	return 0;
}

// private 상속의 경우.
double Student::Average() const
{
	if (ArrayDb::size() > 0)
    	return std::valarray<double>::sum() / std::valarray<double>::size();
    else
    	return 0;

}

여기서 scores는 기초 클래스의 객체이다. 컨테인먼트는 객체를 활용해서 함수를 호출하는 반면, private 상속의 경우는 클래스에서 범위연산자를 사용하여 바로 함수를 호출했다.

근데 만약 객체가 없는 private 상속의 경우에서 객체를 만들고자 하면 어떻게 해야 하는가? → 다음과 같이 데이터형 변환을 하면 된다.

const string & Student::Name() const
{
	return (const string &) *this;
}

Student가 string으로부터 상속되었기 때문에 이 같은 변환이 가능하다.

컨테인먼트와 private 상속 중에 어떤 것을 사용하는 게 이득일까? 역시 각각 장단점이 있다. 컨테인먼트를 사용해야 하는 이유는 다음과 같다.

① 컨테인먼트가 사용하기 편하다.
② 하나 이상의 기초 클래스로부터 상속 받을 때, 상속이 문제를 일으킬 수 있다.

반대로 private 상속을 사용해야 하는 이유는 다음과 같다.

① 기초 클래스의 protected 멤버를 이용하고 싶을 때.
② 가상 함수를 재정의 할 필요가 있을 때.

profile
Question, Think, Select

0개의 댓글