카테고리 없음

[TIL] 언리얼 부트캠프 Day 13 : C++ 템플릿과 STL -> SimpleVector 구현하기

pal2tte 2025. 1. 3. 20:57

오늘은 C++에서 템플릿STL의 활용 방법을 배우며, 이를 기반으로 SimpleVector라는 컨테이너 클래스를 직접 구현해 보았습니다. 이 글에서는 템플릿을 활용한 타입 독립적인 코드 작성, STL과의 비교, 반복자를 활용하는 방법 등을 중심으로 정리하겠습니다.


1. 템플릿을 통한 타입에 독립적인 코드 작성법

C++의 템플릿(template)은 다양한 데이터 타입을 지원하는 범용적인 코드를 작성할 수 있게 해줍니다. 이번에 구현한 SimpleVector는 템플릿을 사용하여 특정 데이터 타입에 의존하지 않고 동적으로 크기를 조정할 수 있는 벡터 컨테이너를 작성했습니다.

템플릿의 기본 구조

템플릿은 다음과 같은 구문으로 작성됩니다:

template <typename T>
class ClassName {
    // 코드 구현
};

이 구문에서 T는 타입 매개변수로, 클래스 또는 함수의 데이터 타입을 나중에 정의할 수 있도록 합니다. 이를 통해 코드의 재사용성이 크게 향상됩니다.

코드에서 템플릿 활용 예시

SimpleVector 클래스는 템플릿을 사용하여 다양한 데이터 타입을 지원합니다:

template <typename T>
class SimpleVector {
private:
    T* data;               // 데이터를 저장할 배열
    int currentSize;       // 현재 원소 개수
    int currentCapacity;   // 배열의 최대 크기

    void resize() {
        currentCapacity *= 2;
        T* newData = new T[currentCapacity];
        for (int i = 0; i < currentSize; ++i) {
            newData[i] = data[i];
        }
        delete[] data;
        data = newData;
    }
    // ...
};

템플릿 덕분에 SimpleVector<int>뿐만 아니라 SimpleVector<std::string>과 같은 다양한 타입으로 사용할 수 있습니다.


2. STL의 컨테이너와 알고리즘

C++ STL의 std::vector는 대표적인 동적 배열 컨테이너로, 다양한 데이터를 효율적으로 저장하고 관리할 수 있습니다. 이번에 작성한 SimpleVector는 STL의 std::vector와 비슷한 구조로 동작하지만, 학습을 위해 STL의 주요 기능을 직접 구현했습니다.

std::vector와의 비교

기능 SimpleVector std::vector

동적 크기 조정 resize()로 직접 구현 내부적으로 자동 처리
데이터 접근 operator[]로 제공 operator[], at() 지원
메모리 관리 수동으로 동적 메모리 해제 RAII를 사용한 자동 메모리 관리

예를 들어, push_back 함수는 std::vector의 push_back과 동일한 기능을 구현합니다.

void push_back(const T& value) {
    if (currentSize >= currentCapacity) {
        resize(); // 용량 초과 시 크기 확장
    }
    data[currentSize++] = value;
}

resize 함수는 STL의 내부 동작과 비슷하게, 크기를 두 배로 늘리며 데이터를 복사합니다.


3. 반복자를 활용해서 컨테이너에 접근하는 방법

STL 컨테이너의 큰 장점은 반복자(iterator)를 사용해 데이터를 순회할 수 있다는 점입니다. 반복자는 컨테이너의 원소에 접근하는 데 사용되는 추상화된 포인터로, STL 알고리즘과도 밀접하게 연결됩니다.

반복자와 SimpleVector

현재 구현한 SimpleVector는 STL처럼 반복자를 지원하지 않지만, 반복자 개념을 클래스에 통합하려면 아래와 같은 방식을 추가로 구현할 수 있습니다:

반복자 클래스 정의

class Iterator {
private:
    T* ptr; // 원소를 가리키는 포인터
public:
    Iterator(T* p) : ptr(p) {}

    T& operator*() { return *ptr; }
    Iterator& operator++() { ++ptr; return *this; }
    bool operator!=(const Iterator& other) const { return ptr != other.ptr; }
};

반복자 인터페이스 추가

Iterator begin() { return Iterator(data); }
Iterator end() { return Iterator(data + currentSize); }

사용 예시

SimpleVector<int> vec;
vec.push_back(1);
vec.push_back(2);
vec.push_back(3);

for (auto it = vec.begin(); it != vec.end(); ++it) {
    std::cout << *it << " ";
}
// 출력: 1 2 3

 


4. 실행 결과

아래는 SimpleVector의 실행 예제입니다:

SimpleVector<int> vec1;
vec1.push_back(1);
vec1.push_back(2);
vec1.push_back(3);
std::cout << "Size: " << vec1.size() << ", Capacity: " << vec1.capacity() << std::endl;

vec1.pop_back();
std::cout << "After pop_back, Size: " << vec1.size() << std::endl;

실행 결과

Size: 3, Capacity: 10
After pop_back, Size: 2

 


5. 결론

이번 글에서는 템플릿을 활용한 SimpleVector 구현을 통해 다음 내용을 학습했습니다:

  1. 템플릿을 사용해 타입 독립적인 코드를 작성하는 방법.
  2. STL 컨테이너와의 유사성과 차이점.
  3. 반복자를 활용해 데이터를 순회하는 방법.

SimpleVector는 STL의 구조를 이해하기 위한 좋은 학습 예제입니다. STL을 사용하는 경우보다 비효율적일 수 있지만, 이를 직접 구현하며 템플릿과 컨테이너의 핵심 개념을 익힐 수 있습니다.