본문 바로가기
개발/C++ (98,03,11,14,17,20,23)

Modern C++ : 클래스 템플릿(Class Template) (98)

by snowoods 2025. 9. 20.

Modern C++

 

클래스 템플릿 (Class Template)

 

개요

클래스 템플릿(Class Template)은 구체적인 데이터 타입을 명시하지 않고, 일반화된(generic) 형태로 클래스를 정의하는 방법입니다. 이를 통해 다양한 자료형에 대해 동일한 동작을 하는 클래스를 한 번만 정의하여 코드의 재사용성을 크게 높일 수 있습니다. 컴파일러는 템플릿에 명시된 타입(예: int, float, double 등)에 맞춰 실제 클래스를 생성합니다.

 

C++ 버전별 주요 키워드 도입 시기

  • C++98: template, typename 키워드를 사용한 클래스 템플릿 기본 기능이 도입되었습니다.

 

내용 설명

클래스 템플릿은 template <typename T> 또는 template <class T> 키워드로 선언을 시작합니다. 여기서 T는 타입 매개변수(type parameter)로, 클래스가 실제 사용될 때 구체적인 자료형으로 대체됩니다.

템플릿으로 정의된 클래스의 멤버 함수들은 클래스 선언과 마찬가지로 템플릿으로 정의되어야 합니다. 일반적으로 클래스 템플릿의 선언과 정의는 모두 헤더 파일(.h, .hpp)에 작성합니다. 이는 컴파일러가 템플릿을 특정 타입의 클래스로 인스턴스화(instantiation)할 때, 템플릿의 전체 코드를 필요로 하기 때문입니다.

 

예제 코드

다음은 2x2 행렬을 나타내는 Matrix 클래스 템플릿 예제입니다.

Matrix.h

#pragma once
#include <iostream>
#include <cstdint>

template <typename T>
class Matrix
{
public:
    Matrix();
    Matrix(const T &A, const T &B, const T &C, const T &D);
    ~Matrix() = default;

    void print_matrix() const;

    T get_A() const;
    T get_B() const;
    T get_C() const;
    T get_D() const;

    void set_A(const T &new_A);
    void set_B(const T &new_B);
    void set_C(const T &new_C);
    void set_D(const T &new_D);

private:
    T m_A;
    T m_B;
    T m_C;
    T m_D;
    std::uint32_t num_rows = 2;
    std::uint32_t num_cols = 2;
};

template <typename T>
Matrix<T>::Matrix() : m_A(T{}), m_B(T{}), m_C(T{}), m_D(T{})
{
}

template <typename T>
Matrix<T>::Matrix(const T &A, const T &B, const T &C, const T &D)
    : m_A(A), m_B(B), m_C(C), m_D(D)
{
}

template <typename T>
void Matrix<T>::print_matrix() const
{
    std::cout << m_A << " " << m_B << '\n';
    std::cout << m_C << " " << m_D << "\n\n";
}

template <typename T>
T Matrix<T>::get_A() const
{
    return m_A;
}

template <typename T>
T Matrix<T>::get_B() const
{
    return m_B;
}

template <typename T>
T Matrix<T>::get_C() const
{
    return m_C;
}

template <typename T>
T Matrix<T>::get_D() const
{
    return m_D;
}

template <typename T>
void Matrix<T>::set_A(const T &new_A)
{
    m_A = new_A;
}

template <typename T>
void Matrix<T>::set_B(const T &new_B)
{
    m_B = new_B;
}

template <typename T>
void Matrix<T>::set_C(const T &new_C)
{
    m_C = new_C;
}

template <typename T>
void Matrix<T>::set_D(const T &new_D)
{
    m_D = new_D;
}

 

main.cpp

#include <iostream>

#include "Matrix.h"

int main()
{
    auto m1 = Matrix<float>(1.0, 2.0, 3.0, 4.0);
    m1.print_matrix();

    auto m2 = Matrix<float>(-1.0, -2.0, -3.0, -4.0);
    m2.print_matrix();

    return 0;
}

 

실행 결과

1 2
3 4

-1 -2
-3 -4

 

활용팁

  • STL 컨테이너: C++ 표준 템플릿 라이브러리(STL)의 std::vector<T>, std::list<T>, std::map<K, V> 등 대부분의 컨테이너는 클래스 템플릿으로 구현되어 있습니다. 이를 통해 어떤 데이터 타입이든 저장할 수 있는 유연한 자료구조를 제공합니다.
  • 코드 재사용: 특정 자료형에 종속되지 않는 알고리즘이나 자료구조를 만들 때 클래스 템플릿을 사용하면 코드 중복을 피하고 유지보수성을 높일 수 있습니다.
  • 컴파일 시간: 템플릿은 컴파일 시간에 코드를 생성하므로, 런타임에 타입을 결정하는 방식(가상 함수 등)에 비해 성능상 이점을 가질 수 있습니다. 반면, 템플릿 인스턴스화가 많아지면 컴파일 시간이 길어지고 실행 파일의 크기가 커질 수 있습니다.