일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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
- 다형성
- 메타테이블
- resource management class
- 스마트 포인터
- effective stl
- 영화 리뷰
- 게임
- lua
- 참조자
- Vector
- 상속
- UE4
- 예외
- 암시적 변환
- 영화
- Smart Pointer
- 루아
- operator new
- virtual function
- 오블완
- 언리얼
- more effective c++
- implicit conversion
- 반복자
- 티스토리챌린지
- c++
- exception
- 비교 함수 객체
- Effective c++
- reference
Archives
- Today
- Total
스토리텔링 개발자
[Effective STL] 1. 컨테이너(Container) 본문
728x90
항목 1. 적재적소에 알맞은 컨테이너를 사용하자
컨테이너의 종류
- 표준 STL 시퀀스(sequence) 컨테이너
- vector, string, deque, list
- 표준 STL 연관(associative) 컨테이너
- set, multiset, map, multimap
- 비표준 시퀀스 컨테이너 (항목 50 참조)
- slist(단일 연결 리스트), rope(대용량 string)
- 비표준 연관 컨테이너 (항목 25 참조)
- hash_set, hash_multiset, hash_map
- 다만 모던 C++에서는 unordered_set, unordered_map 등을 표준으로 지원함.
- string 대신 사용되는 vector<char> (항목 13 참조)
- 간혹 이렇게 쓰면 괜찮을 때가 있다.
- 표준 연관 컨테이너 대신 사용되는 vector (항목 23 참조)
- vector가 수행 속도나 크기 면에서 표준 연관 컨테이너보다 더 나은 경우가 있다.
- STL에 속하지 않는 표준 컨테이너 (항목 16 참조)
- C++ 배열, bitset, valarray, stack, queue, priority_queue
- 하지만 이제 C++ 배열을 제외하고는 모두 STL에 포함된다.
STL 컨테이너의 분류
- 연속 메모리(contiquous-memory) 컨테이너
- 동적 할당된 하나 이상(대개 하나)의 메모리 단위(chunk)에다가 데이터 요소를 저장해 두는 컨테이너.
- 각 청크는 하나 이상의 요소를 담고 있다.
- 삽입, 삭제 시, 같은 청크의 요소들은 앞, 뒤로 밀려나며 새 요소가 삽입될 공간을 만들던가, 지워진 공간을메운다.
- 노드 기반(node-based) 컨테이너
- 동적 할당된 하나의 청크에다가 하나의 요소만을 저장한다.
- 삽입, 삭제 시, 노드의 포인터만이 영향을 받고 노드의 내용은 그대로이다.
어떤 상황에 어떤 컨테이너를 쓰면 가장 좋을까?
- 컨테이너의 아무 위치에 요소를 삽입할 수 있어야 하나?
- 시퀀스 컨테이너를 사용한다.
- 컨테이너 내의 요소들의 순서 결정에 직접 관여해야 하나?
- 해쉬 컨테이너는 사용할 수 없다.
- 표준 C++에 포함된 컨테이너를 사용해야 하나?
- slist, rope는 사용할 수 없다.
- 임의 접근 반복자가 필요한가?
- vector, deque, string, rope(항목 50 참조) 를 사용한다.
- 양방향 반복자가 필요한가?
- slist와 해쉬 컨테이너는 사용할 수 없다.
- 요소 삽입이나 삭제 시 다른 컨테이너 요소들이 밀려나는 일이 없어야 하나?
- 연속 메모리 컨테이너는 사용할 수 없다.
- 컨테이너 내의 데이터가 C의 데이터 타입과 메모리 배열 구조적으로 호환되어야 하나?
- vector만을 사용할 수 있다.
- 탐색 속도가 중요한가?
- 해쉬 컨테이너(항목 25 참조), 정렬된 vector(항목 23 참조), 표준 연관 컨테이너 순으로 고려해본다.
- 컨테이너의 참조 카운팅을 사용하고 싶지 않은가?
- string은 고려하지 않는다.
- 많은 string 코드가 참조 카운팅이 되도록 구현되어 있다.(항목 13 참조)
- rope는 확실히 참조 카운팅 기반으로 구현되어 있다.(항목 50 참조)
- 대신 vector<char>를 사용한다.
- string은 고려하지 않는다.
- 삽입과 삭제 동작이 트랜잭션적인 의미를 가지길 바라는가?
- 즉, 삽입과 삭제 동작을 안정적으로 롤백할 수 있어야 하는가? (항목 17 참조)
- 예외 안전성(exception safety)에 중요한 특징이다.
- 노드 기반 컨테이너를 사용한다.
- 즉, 삽입과 삭제 동작을 안정적으로 롤백할 수 있어야 하는가? (항목 17 참조)
- 반복자, 포인터 참조자가 무효화(invalidation, 포인터가 가리키고 있던 메모리의 실제 내용이 없어짐)되는 일을 최소화해야 하는가?
- 노드 기반 컨테이너를 사용한다.
- 연속 메모리 컨테이너는 전체적인 메모리 재할당이 빈번하므로 무효화되기 쉽다.
-
std::vector<int> vec = {1, 2, 3}; int* ptr = &vec[0]; vec.push_back(4); // 벡터 확장으로 인해 기존 요소의 위치가 변경될 수 있음 // ptr은 이제 유효하지 않음 (invalidated)
-
- 임의 접근 반복자를 지원하는 시퀀스 컨테이너가 필요한데, 요소 삭제가 일어나지 않고 요소 삽입이 컨테이너의 끝에서만 일어나는 한, 포인터와 참조자가 무효화되지 않는 작업이 필요한가?
- deque를 사용한다.
- 요소 삽입이 끝에서 일어날 때, 반복자만 무효화된다.
- 즉, 포인터와 참조자는 무효화되지 않는다.
- STL 컨테이너 중 포인터와 참조자는 보장되고, 반복자만 무효화되는 것은 deque가 유일하다.
- deque를 사용한다.
- 각 컨테이너 타입에서 사용하는 메모리 할당 전략에 따른 고려(항목 10, 항목 14 참조)
728x90
'개발 > Effective STL' 카테고리의 다른 글
[Effective STL] 6. 컴파일러의 분석 오류 (0) | 2024.11.08 |
---|---|
[Effective STL] 5. 범위 멤버 함수(Range Member Function) (0) | 2024.11.07 |
[Effective STL] 4. 빈 컨테이너인지 확인하기 (0) | 2024.11.04 |
[Effective STL] 3. 컨테이너 요소 복사 (0) | 2024.10.31 |
[Effective STL] 2. 컨테이너 독립성(Container-Independent) (2) | 2024.10.30 |
Comments