다들 STL 잘 사용하고 계신가요?
오늘도 라태웅(NHN NEXT, NEXON)님의 발표입니다.
STL의 기본 개념부터, 사용 노하우까지 담아보았습니다.
여러분들도 우리 스터디 참여하셔서 Live로 들으시고 발표도 하러 오세요!
관련 문의 : 댓글 or https://www.facebook.com/gpgstudygogo
1. 1부
프로그래밍 기법들
1.4 게임 프로그래밍에서의 STL 활용 (James Boer)
Page 83 ~ 100
NHN NEXT, NEXON 라태웅
2. STL(Standard Template Library)이 공식적으로 생겨난 때는 1997년
STL은 컨테이너(데이터의 모음) 클래스들의 모음
deque list queue
map multimap set multiset bitset
등이 존재함
priority_qu
eue
stack vector
컨테이너는 시퀀스 컨테이너와 결합 컨테이너로 나뉨
시퀀스 컨테이너
원소들이 직선 순서대로 배치
결합(연관) 컨테이너
레드 블랙 트리, 균형 이진 트리 형태특정 위치에 대한 삽입이 허용되지 않음
3. 반복자
컨테이너 안의 요소들에 대한 포인터와 비슷한 개념
++ 연산자로 반복자를 컨테이너 안의 다음 요소로 옮기는 것
* 연산자로 반복자를 역참조해서 실제 데이터를 얻어오는 것
알고리즘
STL 클래스들에 대해 작동하는 알고리즘, 독립적인 함수로 존재
데이터와 알고리즘을 분리시키기 위해 컨테이너에 포함되지 않음
4. 주요 개념
컨테이너의 시작
begin()
컨테이너의 끝
end()
주의! end()는 마지막 요소가 아니라 마지막 요소 다음의 유효하지 않은 위치를 가리킴
STL 컨테이너들은 정보를 참조(by ref)가 아닌 값(by val)으로 전달
크기가 큰 구조체나 클래스라면 포인터를 넘겨주도록 하는 것이 바람직
그렇지 않으면 매 번의 삽입, 접근마다 객체의 복사를 위해 생성자가 호출된다.
begin() … … … … end()
data data data data data none
5. 벡터
동적으로 크기를 변경할 수 있는 배열
주기적으로 메모리를 재할당하고 새 배열로 데이터를 전송할 수 있는 배열
“크기가 변할 수 있는 배열”이라 함은,
필요한 양 이상의 메모리를 할당할 수 있음
벡터의 끝에 하나의 요소를 추가하는 작업은 “상각된“ 상수적 시간
공간이 꽉 찬 경우,
새 메모리를 할당하고, 기존 메모리에 있는 배열을 새 메모리로 복사하고,
기존 메모리를 해제하는 추가적인 시간과 자원이 소모
메모리를 재할당하면 반복자들이 무효화
새로운 메모리를 할당하고 기존 메모리를 해제하기 때문
메모리 재할당이 언제 일어나는지 이해해야 함
15. 리스트
이중 연결 리스트(Double Linked List)로 구현됨
어떠한 요소 삽입이나 삭제도 상수적인 시간으로 수행됨
연결 리스트이기 때문에 벡터나 데크처럼 특정 요소에 임의 접근은 불가능
벡터와 정확히 동일한 방식으로 사용 가능
push_front(), push_back 등
16.
17.
18. 데크
컨테이너의 양 끝에서 요소의 삽입과 제거가 일어남
컨테이너 중간에서는 요소의 삽입이나 제거가 잦지 않을 때 사용
벡터와 마찬가지로 양 끝에서 삽입과 삭제는 상각된 상수적 시간이 걸린다
큐 자체 내부 데이터의 본성 때문에 임의 접근이 가능하지만 벡터보다 비효율적
시작점이 제일 처음 위치가 아니거나, 등등
none data none
양 끝에서 삽입과 삭제가 일어날 수 있기 때문에 위와 같은 상태일 수 있음
벡터와 달리 추가적인 메모리 할당을 결정할 수 없음
19.
20.
21.
22. 맵
Key-Value 쌍을 담는 컨테이너
해시 테이블보다는 비효율적이지만 속도의 차이는 무시할 수 있을 정도
삽입과 함께 정렬이 수행
즉, map의 데이터는 항상 정렬된 상태로 존재
Key를 통해 값을 조회하는 데 걸리는 시간은 O(log n)
균형 이진 트리 형태(혹은 레드 블랙 트리)의 구조
때문에 O(log n)의 시간이 걸린다
23.
24.
25.
26. 스택
push(), pop(), top()의 기본적인 멤버 함수를 제공
size()와 empty()로 현재 상태를 알 수 있다
스택은 기본적으로 하나의 deque로 구현
stack<int> c; // deque stack
stack<int, vector<int>> c; // vector stack
push_back, pop_back, back() 함수를 제공하는 어떠한 컨테이너라도 vector대신 사용 가능
pop()이나 top()을 수행할 때 항상 검사해야 함
안전성보다는 속도를 우선으로 설계
pop()과 top()을 할 때 스택에 요소가 있는지 size()나 empty()로 미리 점검해 주어야 함
큐와 우선 순위 큐도 마찬가지
27. 큐
push(), pop(), front(), back()의 기본적인 멤버 함수를 제공
size()와 empty()로 현재 상태를 알 수 있다
back()이 요소가 삽입될 위치이다
큐 또한 기본적으로 deque를 사용하나 변경 가능
vector는 앞쪽에서 요소를 추가하거나 제거하면 나머지 요소들이 모두 밀리거나 당겨짐
때문에 vector는 비효율적
우선 순위 큐
큐와 동일하나 삽입과 동시에 내림차순으로 정렬
< 연산자를 기반으로 정렬
때문에 세번째 인자로 사용자 정의 비교 함수를 넣을 수 있음
포인터를 넣었을 경우 주소값을 비교하기 때문에 필수적
28. 결론
STL의 장단점을 잘 이해하면 코드의 속도나 무결성을 훼손하지 않고 강력한 기
능을 최대한 활용할 수 있다
STL은 그 자체만으로 책 한 권을 쓸 수 있는 방대한 주제
이 글을 통해서 STL의 가능성과 매력만을 맛볼 수 있기를 바람
29. 참고 자료
The C++ Standard Library: A Tutorial and Reference
The C++ Programming Language
Designing Components with the C++