c++

C++ 표준 템플릿 라이브러리(STL)와 스마트 포인터

난개발자 2025. 2. 3. 21:07
728x90

1. 표준 템플릿 라이브러리(STL)란?

**표준 템플릿 라이브러리(STL)**는 C++에서 제공하는 강력한 데이터 구조와 알고리즘의 집합입니다. STL은 크게 컨테이너(Containers), 반복자(Iterators), **알고리즘(Algorithms)**으로 구성됩니다.

(1) STL의 주요 구성 요소

  1. 컨테이너(Containers): 데이터를 저장하는 자료구조 (ex. vector, list, map, set)
  2. 반복자(Iterators): 컨테이너의 원소를 순회하는 도구
  3. 알고리즘(Algorithms): 정렬, 검색 등 다양한 알고리즘 제공

2. 주요 STL 컨테이너 사용법

(1) vector: 동적 배열

vector는 크기가 가변적인 동적 배열로, 가장 널리 사용되는 컨테이너 중 하나입니다.

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

int main() {
    vector<int> numbers = {1, 2, 3, 4, 5};

    // 요소 추가
    numbers.push_back(6);

    // 요소 출력
    for (int num : numbers) {
        cout << num << " ";
    }
    cout << endl;

    // 특정 요소 접근
    cout << "첫 번째 요소: " << numbers[0] << endl;

    return 0;
}

출력 결과:

1 2 3 4 5 6
첫 번째 요소: 1

(2) map: 키-값 쌍 저장

map키-값 쌍으로 데이터를 저장하는 연관 컨테이너입니다. 키를 기준으로 자동으로 정렬됩니다.

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

int main() {
    map<string, int> ageMap;

    // 요소 삽입
    ageMap["Alice"] = 30;
    ageMap["Bob"] = 25;

    // 요소 출력
    for (auto& pair : ageMap) {
        cout << pair.first << ": " << pair.second << endl;
    }

    return 0;
}

출력 결과:

Alice: 30
Bob: 25

(3) set: 중복 없는 집합

set중복을 허용하지 않는 데이터를 저장하는 컨테이너입니다.

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

int main() {
    set<int> uniqueNumbers = {1, 2, 3, 2, 4, 5};

    // 요소 출력
    for (int num : uniqueNumbers) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

출력 결과:

1 2 3 4 5

3. STL 알고리즘 사용법

STL은 다양한 알고리즘을 제공합니다. 예를 들어, 정렬, 검색, 변환 등의 기능을 쉽게 사용할 수 있습니다.

(1) 정렬(sort)

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

int main() {
    vector<int> numbers = {5, 2, 9, 1, 5, 6};

    // 오름차순 정렬
    sort(numbers.begin(), numbers.end());

    // 요소 출력
    for (int num : numbers) {
        cout << num << " ";
    }
    cout << endl;

    return 0;
}

출력 결과:

1 2 5 5 6 9

4. 스마트 포인터(Smart Pointers)란?

스마트 포인터는 C++에서 메모리 관리를 자동화하는 포인터입니다. 이를 통해 메모리 누수(memory leak)를 방지할 수 있습니다.

(1) 주요 스마트 포인터 종류

  1. unique_ptr: 하나의 객체를 단독으로 소유하는 포인터
  2. shared_ptr: 여러 포인터가 동일한 객체를 공유할 수 있음 (참조 카운팅)
  3. weak_ptr: shared_ptr과 함께 사용되며, 순환 참조를 방지

(2) unique_ptr 사용법

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

int main() {
    unique_ptr<int> ptr = make_unique<int>(10);
    cout << "값: " << *ptr << endl;

    // unique_ptr은 복사 불가능, 이동만 가능
    unique_ptr<int> ptr2 = move(ptr);
    cout << "이동 후 값: " << *ptr2 << endl;

    return 0;
}

출력 결과:

값: 10
이동 후 값: 10

(3) shared_ptr 사용법

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

int main() {
    shared_ptr<int> ptr1 = make_shared<int>(20);
    shared_ptr<int> ptr2 = ptr1;  // 참조 카운트 증가

    cout << "값: " << *ptr1 << endl;
    cout << "참조 카운트: " << ptr1.use_count() << endl;

    return 0;
}

출력 결과:

값: 20
참조 카운트: 2

(4) weak_ptr 사용법

weak_ptr은 순환 참조(Circular Reference)를 방지하기 위해 사용됩니다.

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

int main() {
    shared_ptr<int> sharedPtr = make_shared<int>(30);
    weak_ptr<int> weakPtr = sharedPtr;

    cout << "참조 카운트: " << sharedPtr.use_count() << endl;

    if (auto locked = weakPtr.lock()) {
        cout << "weak_ptr이 가리키는 값: " << *locked << endl;
    } else {
        cout << "객체가 더 이상 존재하지 않습니다." << endl;
    }

    return 0;
}

출력 결과:

참조 카운트: 1
weak_ptr이 가리키는 값: 30

 

728x90