이번 항목은 저번 13항목, 14항목에서 만들어보았던 private 기반 상속과 HAS-A 기반 관계에 대해 비교해 보는 항목이다.
생각해 보자.
이 책의 저자인 허브 셔터 역시, 각 역활은 각 독립체에게 맞기는게 더 좋다라고 설명한다. 관계가 엮이면 엮 일 수록 엮인 만큼 풀 수 없다는 노리와 일맥상통한다.
private 상속은
등을 꼽을 수 있겠다.
T의 요구사항이 특정 함수를 요구한 다든지, 특정 클래스를 상속 해야 한다든지 한다면, 특정된 개체에 대해서만 사용 될 수밖에 없다는 이야기일 뿐이다.(경우에 따라서 이런 경우도 필요 하다. .. 왕도 없는 프로그래머의 길)
그렇다면 현재의 Stack의 데이터형 T의 요구사항은 무엇일까?
이 요구사항 중 기본 생성자의 경우, 컨테이너는 배열형태로 메모리를 할당하기 위하여 기본 생성자가 필요하지 않을까 하지만, 현재의 Stack 컨테이너는 초기 메모리를 객체형이 아닌 공간 크기로 생성하므로써 T의 기본 생성자 요구 사항을 없앴다.
이것을 기반으로 하기 때문에 placement new 를 사용 하였으며, push 할 경우에도 그 메모리 공간에 T의 복사 생성자를 호출하여 기록한다. 이것으로 T의 요구사항 복사 할당자를 제외 시켰다.
그렇기 때문에 단 두개의 요구 사항만을 요구 하게 된다.
소멸자에서 예외를 발생시키지 않는다는 것은, 기본 사항이니 패스.
제공 안해도 될 때, 두가지 큰 변명 거리가 있다.
이 점을 유의하고 예외 발생 을 제공한다면, 그 규격을 제공하고, 심사 숙고 해야 할 것이다.
- StackImple을 private 기반 클래스나 멤버 개체로 사용하는 것 중에 어느 기법이 더 좋은가?
- Stack의 두 버전은 얼마나 재사용 가능한가? 내재된 데이터형인 T의 요구사항은 무엇인가?
- Stack은 함수에 대한 예외 규격을 제공해야 하나?
생각해 보자.
1. private 상속이 좋은가? HAS-A 관계가 좋은가?
왜 이런 비교를 하는고 하면, 두 상속 모두 "구현 상속" 이라는 명제가 깔리기 때문이다. 클래스 기반 상속은 HAS-A 기반 관계 보다 더 관계를 맺는다.. 마치 머리에 붙은 껌 같이 강력하다. 그렇기 때문에 대부분의 사람들은 HAS-A 관계으로도 충분하다면, 굳이 클래스 기반 상속을 사용하지 않는다.이 책의 저자인 허브 셔터 역시, 각 역활은 각 독립체에게 맞기는게 더 좋다라고 설명한다. 관계가 엮이면 엮 일 수록 엮인 만큼 풀 수 없다는 노리와 일맥상통한다.
private 상속은
- 클래스의 protected 멤버를 접근할 필요가 있을 때
- 가상 함수를 오버로드 해야 할 때
- 다른 기반 서브 개체들 전에 개체가 생성되어야 할 때
- 공간 최적화를 하려 할 때
- 상속 기반 트릭을 쓰려 할 때(상속해야 지만 쓸 수 있는 트릭:noncopyable 클래스 류)
등을 꼽을 수 있겠다.
2. Stack의 얼마나 재사용 가능한가? 데이터형 T의 요구 사항은?
왜 T의 요구사항까지 알아야 하는고 하면, Stack 자체가 T의 몇가지 연산자가 있어야지만 가능하기 때문이다. 이것으로 Stack의 재사용은 T의 요구사항이 적으면 적을 수록 극대화 시킬 수 있다.T의 요구사항이 특정 함수를 요구한 다든지, 특정 클래스를 상속 해야 한다든지 한다면, 특정된 개체에 대해서만 사용 될 수밖에 없다는 이야기일 뿐이다.(경우에 따라서 이런 경우도 필요 하다. .. 왕도 없는 프로그래머의 길)
그렇다면 현재의 Stack의 데이터형 T의 요구사항은 무엇일까?
- 복사 생성자( Push 할 때, 생성자로 복사 해서 들어가기 때문에)
- 예외를 발생시키지 않는 소멸자( 이건 기본 사항... )
이 요구사항 중 기본 생성자의 경우, 컨테이너는 배열형태로 메모리를 할당하기 위하여 기본 생성자가 필요하지 않을까 하지만, 현재의 Stack 컨테이너는 초기 메모리를 객체형이 아닌 공간 크기로 생성하므로써 T의 기본 생성자 요구 사항을 없앴다.
이것을 기반으로 하기 때문에 placement new 를 사용 하였으며, push 할 경우에도 그 메모리 공간에 T의 복사 생성자를 호출하여 기록한다. 이것으로 T의 요구사항 복사 할당자를 제외 시켰다.
그렇기 때문에 단 두개의 요구 사항만을 요구 하게 된다.
소멸자에서 예외를 발생시키지 않는다는 것은, 기본 사항이니 패스.
3. Stack은 함수에 대한 예외 규격을 제공 해야 하는가?
제공해도 되며, 안해도 된다. 하지만 제공 하려 할 땐, Stack 의 재사용성을 어디까지 해야 할 것인가에 대해서 고려해 봐야 한다. 그래서 "제공 안해도 된다" 라는 말이 나오곤 한다.제공 안해도 될 때, 두가지 큰 변명 거리가 있다.
- throw()를 작성하면, 클래스 파생자에게 자동적으로 throw() 를 요구하게 됨으로 써 제한을 주게 된다.
- 예외 규격은 예외를 발생하던 안하던, 성능 과부하를 가져 오게 된다
이 점을 유의하고 예외 발생 을 제공한다면, 그 규격을 제공하고, 심사 숙고 해야 할 것이다.
총평
컨테이너에 대해서 좀 더 생각해 보는 계기가 되었다. 한 가지 사실을 알게 되었다. 바로 placement new 를 이용하면 기본 생성자 없이도 배열 형태로 메모리를 쓸 수 있다는 것, .. 공간 낭비가 심하지 않을까 했지만, 오히려 공간 최적화가 되는구나 라고 생각 된다.(new 할당시 8바이트 정렬과 앞뒤에 붙은 헤더메모리(.. 기록하기 위한)을 사용 하기 때문인데, Stack은 size 단위로 메모리 잡기 때문에 오히려 공간 최적화가 되지 않을까 한다.)'책 정리 > Exceptional C++' 카테고리의 다른 글
Exceptional C++ 차례 (0) | 2008.12.01 |
---|---|
항목 19 : 코드 복잡성 - 파트 2 (난이도 7) (0) | 2008.12.01 |
항목 17 : 예외에 안전한 코드를 작성하기 - 파트 10 (난이도 9/½) (0) | 2008.11.29 |
항목 16 : 예외에 안전한 코드를 작성하기 - 파트 9 (난이도 8) (0) | 2008.11.28 |
항목 14 : 예외에 안전한 코드를 작성하기 - 파트 7 (난이도 5) (0) | 2008.11.26 |
항목 13 : 예외에 안전한 코드를 작성하기 - 파트 6 (0) | 2008.11.25 |
항목 24 : 상속의 사용과 남용 (난이도 6) (2) | 2008.10.26 |
항목 23 : 클래스 관계 - 파트 2 (난이도 6) (0) | 2008.10.25 |
항목 22 : 클래스 관계 - 파트 1 (난이도 5) (0) | 2008.10.19 |
항목 21 : 가상 함수들의 재정의 (난이도 6) (0) | 2008.10.19 |
최근댓글