
컨테이너 어댑터(container adapter)를 간단ㄷ하게 요약하면, 다른 컨테이너를 기반으로 새로운 기능을 제공하는 컨테이너 라고 말할 수 있다. 즉, 기존의 컨테이너를 감싸서 새로운 인터페이스를 제공한다.
예를 들어 std::stack 컨테이너 어댑터는 std::vector 컨테이너를 기반으로 LIFO (Last In First Out) 자료 구조를 제공하고, std::queue 컨테이너 어댑터는 std::deque 컨테이너를 기반으로 FIFO (First In First Out) 자료 구조를 제공한다.
컨테이너 | 헤더 | 설명 |
|---|---|---|
| stack | <stack> | LIFO 스택 |
| queue | <queue> | FIFO 큐 |
std::stack은 C++ 표준 템플릿 라이브러리에서 제공하는 컨테이너 어댑터 중 하나로, 스택(stack) 자료구조를 구현하는 데 사용한다.
스택은 데이터를 차례대로 쌓고 가장 마지막에 넣은 데이터를 가장 먼저 꺼낸다. 이를 후입 선출, 영어로는 Last In First Out (LIFO)라고 한다. 이러한 특성 때문에 스택은 데이터를 임시로 저장하거나 역순으로 처리할 때 주로 사용한다.
std::stack<데이터_형식> 객체_이름;
스택에 데이터를 넣을 때는 push 함수를 사용하고 데이터를 맨 위쪽에 쌓는다. 스택에 데이터를 꺼낼 때는 pop 함수를 사용하고 맨 위쪽의 데이터를 제거한다.스택에서 맨 위쪽의 값은 top 함수로 확인할 수 있다.다음은 스택 컨테이너를 활용하는 예제이다.
#include <iostream>
#include <stack>
using std::cout;
using std::endl;
int main()
{
std::stack<int> myStack;
// 스택에 데이터 추가
myStack.push(1);
myStack.push(2);
myStack.push(3);
// 스택의 맨 위쪽 값 확인
cout << "맨 위의 원소: " << myStack.top() << endl;
// 스택에서 데이터 제거(맨 위쪽 값 제거)
myStack.pop();
cout << "맨 위의 원소 제거 후, 새로운 맨 위의 원소: " << myStack.top() << endl;
// 스택의 크기(데이터 개수) 확인
cout << "스택 크기: " << myStack.size() << endl;
// 스택이 비었는지 확인
if (myStack.empty()) {
cout << "스택이 비어있습니다." << endl;
}
else {
cout << "스택이 비어있지 않습니다." << endl;
}
return 0;
}
실행 결과
맨 위의 원소: 3
맨 위의 원소 제거 후, 새로운 맨 위의 원소: 2
스택 크기: 2
스택이 비어있지 않습니다.
스택은 컴퓨터 과학과 프로그래밍에서 중요한 자료 구조로, 다양한 응용 분야에서 사용된다. 특히 함수 호출과 관련된 작업을 효율적으로 처리하기 위해 만들어졌다고 할 수 있다.
스택이 만들어진 주된 이유와 목적을 정리하면 다음과 같다.
함수 호출 관리데이터 임시 저장역순 처리재귀 알고리즘컴퓨터 아키텍처컴파일러와 언어 구현std::queue는 C++ 표준 템플릿 라이브러리에서 제공하는 컨테이너 어댑터 중 하나로, 큐(queue) 자료 구조를 구현하는 데 사용한다. 큐는 가장 먼저 넣은 데이터를 가장 먼저 꺼낸다. 이를 선입 선출, 영어로는 First In First Out (FIFO)라고 한다.
C++ 표준 템플릿 라이브러리에서 큐는 내부적으로 덱(std::deque) 컨테이너를 사용한다. 덱은 양쪽 끝에서 삽입과 삭제가 효율적이므로 큐에 적합한 구조이다.
큐 컨테이너는 동작 방법이 매우 직관적이므로 활용 예를 보면서 각 멤버 함수를 어떻게 사용하는지 확인해보자.
#include <iostream>
#include <queue>
using std::cout;
using std::endl;
int main()
{
std::queue<int> myQueue;
// 삽입
myQueue.push(1);
myQueue.push(2);
myQueue.push(3);
cout << "큐의 맨 앞: " << myQueue.front() << endl;
cout << "큐의 맨 뒤: " << myQueue.back() << endl;
// 꺼내기
myQueue.pop();
cout << "pop() 후의 큐의 맨 앞: " << myQueue.front() << endl;
cout << "pop() 후의 큐의 맨 뒤: " << myQueue.back() << endl;
// 비었는지 확인
cout << "큐가 비었는가? " << (myQueue.empty() ? "네" : "아니오") << endl;
// 크기 구하기
cout << "큐의 크기: " << myQueue.size() << endl;
return 0;
}
실행 결과
큐의 맨 앞: 1
큐의 맨 뒤: 3
pop() 후의 큐의 맨 앞: 2
pop() 후의 큐의 맨 뒤: 3
큐가 비었는가? 아니오
큐의 크기: 2
큐는 데이터의 순서를 보장하고 특히 선입 선출 특성 덕분에 먼저 들어온 데이터가 먼저 처리되어야 하는 상황에서 효과적으로 사용된다. 대표적으로 다음과 같은 상황에서 유용하게 활용할 수 있다.
작업 대기열이벤트 처리멀티스레딩 환경에서 동기화너비 우선 탐색캐시 구현