CS/C++

뇌를 자극하는 C++ STL : 5장. STL 소개

샤아이인 2022. 1. 18.

내돈내고 내가 공부한것을 올리며, 중요한 단원은 저 자신도 곱씹어 볼겸 가겹게 포스팅 하겠습니다.

1) 5장. STL 소개

STL의 간략한 소개와 기본 구성요소에 대해 살펴보았다.

 

STL의 구성 요소

- 컨테이너(Container): 객체를 저장하는 객체로 컬렉션 혹은 자료구조라고도 합니다.

- 반복자(Iterator): 포인터와 비슷한 개념으로 컨테이너의 원소를 가리키고, 가리키는 원소에 접근하여 다음 원소를 가리키게 하는 기능

- 알고리즘(Algorithm): 정렬, 삭제, 검색, 연산 등을 해결하는 일반화된 방법을 제공하는 함수 템플릿.

- 함수객체(Funtion Object): 함수처럼 동작하는 객체로 operator() 연산자를 오버로딩한 객체입니다.

- 어댑터(Adaptor): 구성 요소의 인터페이스를 변경해 새로운 인터페이스를 갖는 구성 요소로 변경합니다.

- 할당기(Allocator): 컨테이너의 메모리 할당 정책을 캡슐화한 클래스 객체로 모든 컨테이너는 자신만의 기본 할당기를 가지고 있습니다. 프로그램 대부분은 STL에서 제공하는 기본 할당기만으로 충분하므로 자세히 다루지 않습니다.

 

컨테이너

- 표준 시퀀스 컨테이너: 컨테이너 원소가 자신만의 삽입 위치(순서)를 가지는 컨테이너

-> vector, deque, list, array, forward_list

 

- 표준 연관 컨테이너: 저장 원소가 삽입 순서와 다르게 특정 정렬 기준에 의해 자동 정렬되는 컨테이너

-> set, multiset, map, multimap

 

반복자

반복자는 포인터와 비슷하게 작동한다. 컨테이너에 저장된 원소를 순회하고 접근하는 일반화된 방법을 제공합니다.

반복자는 컨테이너와 알고리즘이 하나로 동작하게 묶어주는 인터페이스 역할을 합니다.

 

반복자는 다음과 같이 다섯 범주로 나뉩니다.

- Input iterator: 현 위치의 원소를 한번만 읽을 수 있는 반복자.

- Output iterator: 현 위치즤 원소를 한번만 쓸 수 있는 반복자.

- forward iterator: 입력, 출력 반복자 기능에 순방향으로 이동(++)이 가능한 재할당될 수 있는 반복자.

- bidirectional iterator: forward iterator기능에 역방향으로 이동(--)이 가능한 반복자. (list, set, multiset, map, multimap)

- random access iterator: 양방향 반복자 기능에 +, -, +=, -=, [] 연산이 가능한 반복자. (vector, deque)

 

 

어댑터

『컨테이너 어댑터는 순차열 컨테이너를 다른 기능을 제공하는 순차열 컨테이너로 정의하기 위해 래핑하는 클래스 템플릿을 말한다. 다른 기능을 제공하기 위해 컨테이너의 기존 인터페이스를 확장(adapt)하기 때문에 이런 클래스 템플릿을 어댑터 클래스(adapter class)라 부른다. (C++14 STL 철저 입문)』

 

STL의 어댑터 로는 컨테이너 어댑터, 반복자 어댑터, 함수 어댑터가 있습니다.

- container adaptor: stack, queue, priority_queue

- iterator adaptor: reverse_iterator, back_insert_iterator, front_insert_iterator, insert_iterator

- function adaptor: binder. negator, adaptor for pointers to functions

 

대표적인 컨테이너 어댑터가 Stack 이다. Stack 어댑터를 활용하면 일반 컨테이너를 LIFO방식의 Stack 컨테이너로 변환합니다.

empty, size, push_back, pop_back, back 인터페이스(멤버 함수)를 지원하는 컨테이너는 모두 Stack 컨테이너 어댑터를 사용하여 LIFO 방식의 Stack으로 변환할 수 있습니다.

 

모든 시퀀스 컨테이너는 empty, size, push_back, pop_back, back 인터페이스를 가지므로 stack컨테이너 어댑터의 컨테이너로 사용될 수 있습니다.

 

대표적인 반복자 어댑터가 reverse_iterator입니다. reverse_iterator는 일반 반복자의 동작 방식을 반대로 동작시키는 역방향 반복자 로 변환합니다.

 

『반복자 어댑터는 표준 반복자에 특별한 동작을 제공하는 클래스 템플릿이므로 반복자 템플릿에서 파생되었다.

어댑터 클래스 템플릿에서 정의하는 반복자는 역방향 반복자, 삽입 반복자, 이동 반복자 세 가지다.

이들 템플릿 클래스는 reverse_iterator, insert_iterator, move_iterator에 정의되어 있다.(C++14 STL 철저 입문)』

 

 

다음 코드는 반복자 어댑터를 이용해 vector의 반복자를 역방향 반복자로 변경한 예제입니다.

#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector<int> v;

	v.push_back(10);
	v.push_back(20);
	v.push_back(30);
	v.push_back(40);
	v.push_back(50);

	for (vector<int>::iterator iter = v.begin(); iter != v.end(); iter++)
		cout << *iter << " ";
	cout << endl;

	// 역방향 반복자로 변환
	reverse_iterator<vector<int>::iterator> riter(v.end());
	reverse_iterator<vector<int>::iterator> end_riter(v.begin());

	for (; riter != end_riter; ++riter)
		cout << *riter << " ";
	cout << endl;
 
	return 0;
}
 

결과는 다음과 같다.

또한 모든 컨테이너는 자신의 역방향 반복자를 typedef 타입으로 정의하며 rbegin()과 rend() 멤버 함수로 순차열의 시작과 끝 원소를 가리키는 반복자 쌍을 반환합니다.

 

할당기

할당기는 컨테이너의 메모리 할당 정보와 정책을 캡슐화한 STL 구성 요소입니다. 모든 컨테이너는 기본 할당기를 사용합니다.

C++의 동적 메모리 할당에 사용하는 new와 delete가 오버로딩 가능하듯, STL의 할당기도 사용자가 직접 할당기를 정의하고 사용할 수 있다.

 

모든 컨테이너는 템플릿 매개변수에 할당기를 인자로 받습니다.

 

 

책을 읽다보니 논리적이지 못한 부분을 발견하여 오탈자 확인신청을 하였다. cpp reference 에서 확인한 결과 나의 생각이 정확한것같다.

 

2) 나의 현황

- 어뎁터에 관한 내용을 내일 조금더 확인해 봐야겠다. 저녁이라 그런지 머리가 내용을 잘 이해하지 못한것 같다. (2021/02/10)

- 맑은 정신으로 다시 보니 좀더 이해가 잘됬다. 또한 C++14 STL 철처 입문이라는 책을 조금더 참고하여 세부사항을 읽어보았다. 역방향 반복자가 조금더 이해가 잘 된것 같다. (02/11)

이글의 모든 사진과 내용의 출처는 공동환 님께 있습니다.

댓글