일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
Tags
- more effective c++
- 루아
- 영화
- Effective c++
- effective stl
- lua
- 게임
- 비교 함수 객체
- 언리얼
- UE4
- reference
- exception
- 오블완
- 상속
- 암시적 변환
- Smart Pointer
- 메타테이블
- 스마트 포인터
- operator new
- resource management class
- 영화 리뷰
- 예외
- 다형성
- 참조자
- implicit conversion
- virtual function
- 티스토리챌린지
- Vector
- c++
- 반복자
Archives
- Today
- Total
스토리텔링 개발자
[Effective C++] 38. 객체 합성 본문
728x90
항목 38 : “has a(~는 ~를 가짐)” 혹은 “is implemented in terms of(~는 ~를 써서 구현됨)”를 모형화할 때는 객체 합성을 사용하자.
합성(composition)
- 객체가 다른 타입의 객체를 포함하고 있을 경우 성립하는 타입들 사이의 관계
- 레이어링(layering), 포함(containment), 통합(aggregation), 내장(embedding) 등으로도 불린다.
class Address { ... };
class PhoneNumber { ... };
class Person
{
public:
...
private:
// 아래 객체들은 Person 객체와 합성 관계이다.
string name;
Address address;
PhoneNumber voiceNumber;
PhoneNumber faxNumber;
};
객체 합성의 의미 두 가지
- 상속의 의미
- is a(...는 ...의 일종이다.)
- 합성의 의미
- has a(...는 ...를 가진다.)
- is implemented in terms of(...는 ...를 써서 구현된다.)
- 뜻이 두 가지인 이유는, 소프트웨어 개발에서 우리가 대하는 영역(domain)이 두 가지이기 때문이다.
영역의 종류
- 응용 영역(application domain)
- 객체 중 일상 생활에서 볼 수 있는 사물을 본 뜬 것들.
- 사람, 이동수단, 비디오 프레임 등.
- has a
- 구현 영역(implementation domain)
- 시스템 구현만을 위한 인공물.
- 버퍼, 뮤텍스, 탐색 트리 등.
- is implemented in terms of
예제로 알아보는 is-a 관계와 is-implemented-in-terms-of 관계의 차이점
- set 템플릿을 사용하려는 경우에 대해 생각해보자.
- std::set의 경우 원소 한 개당 포인터 세 개의 오버헤드가 걸리는 것이 마음에 걸린다.
- 균형 탐색 트리(balanced search tree)로 구현되어 있기 때문.
- set 템플릿을 만들되 list에서 파생된 형태부터 시작하도록 만들어보자.
-
template<typename T> // list를 잘못 사용하는 방법 class Set : public std::list<T> { ... };
- 허나, list와 set은 is-a 관계가 될 수 없다.
- list는 중복 원소를 가질 수 있는 컨테이너이기 때문이다.
- set 객체는 list 객체를 써서 구현되는(is implemented in terms of) 형태의 설계가 되어야 한다.
-
template<class T> class Set { public: bool member(const T& item) const; void insert(const T& item); void remove(const T& item); std::size_t size() const; private: std::list<T> rep; // list를 합성 }; template<typename T> bool Set<T>::member(const T& item) const { return std::find(rep.begin(), rep.send(), item) != rep.end(); } template<typename T> void Set<T>::insert(const T& item) { if(!member(item)) rep.push_back(item); } template<typename T> void Set<T>::remove(const T& item) { typename std::list<T>::iterator it = std::find(rep.begin(), rep.end(), item); if(it != rep.end()) rep.erase(it); } template<typename T> std::size_t Set<T>::size() const { return rep.size(); }
- std::set의 경우 원소 한 개당 포인터 세 개의 오버헤드가 걸리는 것이 마음에 걸린다.
728x90
'개발 > Effective C++' 카테고리의 다른 글
[Effective C++] 40. 다중 상속 (0) | 2024.07.10 |
---|---|
[Effective C++] 39. private 상속 (0) | 2024.07.09 |
[Effective C++] 37. 상속된 함수의 매개변수 기본값 재정의 문제 (0) | 2024.07.05 |
[Effective C++] 36. 상속된 비가상 함수 이름 가리기 문제 (0) | 2024.07.05 |
[Effective C++] 35. 일반 가상 함수 외의 구현법 (0) | 2024.07.04 |
Comments