Recommanded Free YOUTUBE Lecture: <% selectedImage[1] %>

Standard C++ Library('''STL''') 배워보기

Contents

개요

  • 이 글은 필자의 소견이 다소 주관적으로 들어갈수 있습니다. 반대의견이나 좋은 내용 있으면 글 남겨주세요.

STL이란

  1. 국제표준기구(International Standards Organization: ISO) 와 미국국가표준기관(American National Standards Institute: ANSI) 에서 C++ 언어에 대한 표준을 마련하는 노력이 있었으며 이중에 하나가 바로 STL입니다. 여기서 마련된 라이브러리는 다음과 같은 요소를 가지고 있습니다.
    • 표준템플릿라이브러리 (Standard Template Library: STL) - 이것은 데이터 구조와 그에 대한 알로리즘을 구현하는 것에 대하여 특별히 요소로 분리됩니다.
    • I/O stream (입/출력 흐름 요소)
    • 국제화 관련 요소
    • Memory 관리요소
    • 문자열/복소수/수치제한 템플릿 클래스
    • 예외 처리에 대한 제어요소
    • 그 밖에 ... (필자는 더이상 뭐가 있는지 잘 모름)
  2. STL은 그 구조적인 목적을 만족하기 위해서 복잡한 계층적 구조와 상속의 개념을 피하고 있습니다. 이것은 C++의 장점을 살리기 보다는 최적화에 중점을 두어 구성된 것이므로 사용자는 이 특성을 적절히 보다 폭 넓게 사용할수 있게 합니다. 만약 이를 C++의 객체지향성의 모든 요소를 사용하여 만든다면 사용상 간편한 부분은 있을지 모르겠으나 속도 및 크기 면에서 만족할수 없는 결과가 발생합니다. 적어도 프론트엔드에서는 객체지향적인 설계가 유리할지 모르지만 백엔드에서는 이러한것이 오히려 성능에 악영향을 발생할수 있을겁니다. 그 만큼 H/W의 사양을 높여야 하고 그 만큼 드는 비용적인 지출이 크게 될것이 뻔합니다.
  3. STL은 Thread환경에서 굉장히 조심성 있게 사용해야 합니다. (즉, STL은 경쟁적 조건상에 놓인 데이터를 보장해주지 않습니다.) 제 아무리 잘 만든다고 하여도 Safe thread 코드는 그만큼 경쟁조건에 대한 처리로 인하여 CPU를 과소비하게 될수밖에 없습니다. 때문에 개발자는 편리함을 강조하기 보다는 설계적인 요소를 충분히 고려하여 이를 극복해야 합니다.
  4. STL은 크게 3가지 요소를 사용하여 고려되는데 데이터 형식, 데이터 전달방식, 알고리즘 이 그것입니다. 이를 C++에서 Template 기능을 적극 활용하여 많은 코드분량을 줄일수 있도록 됩니다. 모든 개발자는 이러한 3가지의 요소를 충분히 간파하여 설계를 해야 하며 그에 따르는 성과를 직접 느껴볼수 있게 될것입니다.

준비 학습

템플릿 (Template)

  • Template에 대한 준비 학습을 위한 장입니다. 저도 Template는 기본적인 내용만 알고 있거든요 이번참에 제대로 한번 :-) - [yundream]
  • Template는 일종의 반복되는 구조를 갖지만 데이터의 형식이 다른 경우 반복적인 코딩을 피하고 보다 간략한 표현으로 여러 종류의 코드를 생성한 효과를 얻는것을 말합니다. 다음의 예제는 2개의 값을 받아서 평균을 구합니다. 중요한것은 이것 하나로 char, int, float, double 등에 대한 개별적인 코드가 아래의 Template구조로 간결하게 표현된것입니다.

구현

반복자 (Iterator)

  • 특정 포인터의 Offset을 조작하는 것으로 ptr, ptr + i, ptr[i], ptr->next 등의 구현이 이에 속합니다. 각 알고리즘에 따라서 적당한 오퍼레이션으로 구현되며 어떤것을 선택하는가는 STL구조적 특성과 프로그래머의 선택에 달려있습니다.

범위지정

  • 어떤 데이터의 처음과 끝을 가리키는 것으로 데이터가 어디부터 어디까지 몇개가 있는지를 유지할수 있는 범위를 나타내는 것이 필요합니다. 보통 2중 연결 리스트에서 처음과 끝에 NULL을 갖는것과 같이 이를 x.begin() 과 x.end() 로 나타내며 여기서 x.end()는 마지막 원소를 가르키지 않는다는 점에서 주의가 필요합니다. x.end()는 가장 마지막 데이터 원소의 다음을 나타내는 NULL을 갖습니다. 상황에 따라서 각 원소가 NULL을 가르키는 경우가 있는데 프로그래머는 이에 주의해서 개발하여야 합니다. 마지막 원소를 얻으려면 x.rbegin()을 사용할수 있으며 역참조도 가능하다는 것입니다.
  • x.end()가 NULL을 갖는것이 유용한 이유는 데이터가 전혀 없는지를 다음과 같이 할수 있다는 점에서 편리한 부분이 보입니다.
  • 범위지정 원소사이에 데이터는 메모리상에 연속적으로 있다는 보장을 할수 없으며 단지 논리적인 연속성을 갖는다고 생각하면 맞습니다. 이러한 논리적 연속성은 STL이 잘 관리해주지만 특별히 프로그래머의 실수로 특성을 잘못 사용하면 프로그램은 곧 죽는것을 볼수 있을겁니다.

반복자의 종류

  • 반복자의 종류로는 아래의 표와 같이 5가지가 존재하지만 상호 계측적인 구현이 되어 있습니다. 즉, 순방향 반복자를 예로 들자면 입력 반복자와 출력 반복자가 순방향 반복자에서 사용될수 있습니다.
|| 종류 || 접근속성 || 접근방향 || 계층적 요소 || 가능한 연산자 ||
임의의 접근 반복자 읽기/쓰기 특정 위치 접근 양방향 {{{=(*ptr), (*ptr)=, ->, [], ++, --, +, -, +=, -=, ==, !=, <, >, <=, >=}}}
양방향 반복자 읽기/쓰기 순방향/역방향 순방향, 역방향 {{{=(*ptr), (*ptr)=, ->, ++, --, ==, !=}}}
순방향 반복자 읽기/쓰기 순방향 입력, 출력 {{{=(*ptr), (*ptr)=, ->, ++, ==, !=}}}
입력 반복자 읽기 순방향 {{{=(*ptr), ->, ++, ==, !=}}}
출력 반복자 쓰기 순방향 {{{(*ptr)=, ++}}}

데이터 전달방식 (Container)

  • 데이터 전달방식은 몇가지가 있는데 이중에서 자신의 설계에 가장 적합한 것을 선택해야 합니다.

deque (Double ended queue)

  • 앞/뒤 양쪽에서 삽입과 삭제가 가능하며 list, vector의 요소를 모두 내포하고 있습니다.

list

  • 임의의 위치에 삽입과 삭제가 빠릅니다.

map

  • Key를 사용하여 접근하며 삽입과 삭제가 빠릅니다.

multimap

  • 중복 가능한 Key를 사용하는 map입니다.

multiset

  • 중복이 가능한 set입니다.

priority_queue

  • 가장 큰 값을 갖는 데이터로의 접근과 삭제가 빠릅니다.

queue

  • 삭제는 앞에서, 삽입은 뒤에서만 가능한 FIFO와 유사한 구조입니다.

set

  • 삽입과 삭제 그리고 값의 여부 검사가 빠릅니다. 이것은 삽입되는 순서가 중요합니다.

stack

  • FILO와 유사한 구조로 한쪽에서만 삽입과 삭제가 가능합니다.

vector

  • 임의의 위치에 접근하며 뒤에서 삽입이 빠릅니다.

관련 문서들

  1. STL 개요
  2. Sequence Container
  3. Association container
  4. Iterator
  5. 알고리즘

마지막으로