반응형
이상하게 반복되는 템플릿 패턴
CRTP(Curiously Recurring Template Pattern)는 클래스 x가 x 자체를 사용하는 클래스 템플릿 인스턴스화에서 파생되는 C++의 관용어이다. 이를 통해 가상 함수 없이도 동일한 함수를 여러 클래스에서 사용할 수 있는 정적 다형성을 구현할 수 있다. 하지만 이 패턴을 사용하는데는 몇 가지 문제가 있는데 주요 문제 중 하나는 메서드 숨김으로, 파생 클래스가 부모 클래스의 메서드를 실수로 숨실 수 있다는 것이다. (동일한 메서드명으로 선언) 추가로 CRTP 기본 클래스가 템플릿이어야 하므로 복잡성이 증가되고 디버깅하기 어려운 오류가 발생할 수 있다는 것이다.
메서드 숨김 문제를 해결하려면 베이스 클래스에서 메서드를 선언할 때 가상 키워드(virtual)를 사용하는 것이 좋다. 이렇게 하면 모든 파생 클래스가 기본 클래스의 메서드를 상속하게 된다. CRTP를 방문자 패턴과 결합하여 객체의 유형에 따라 다른 동작을 구현할 수 있다.
예제
이상하게 반복되는 템플릿 패턴은 클래스 X가 클래스 템플릿 Y에서 파생되는 관용어로, 템플릿 매개변수 Z를 취하며, 여기서는 Y는 Z = X로 인스턴트화 된다. 예를 들어
template<class Z>
class Y {};
class X : public Y<X> {};
기본 클래스가 인터페이스를 노출하고 파생 클래스가 해당 인터페이스를 구현하는 '컴파일 타임 다형성(Compile-time Polymorphism)'을 구현하는데 CRTP를 사용할 수 있다.
#include <iostream>
template <class Derived>
struct Base { void name() { (static_cast<Derived*>(this))->impl(); } };
struct D1 : public Base<D1> { void impl() { std::cout << "D1::impl()\n"; } };
struct D2 : public Base<D2> { void impl() { std::cout << "D2::impl()\n"; } };
int main()
{
Base<D1> b1; b1.name();
Base<D2> b2; b2.name();
D1 d1; d1.name();
D2 d2; d2.name();
}
Output :
D1::impl()
D2::impl()
D1::impl()
D2::impl()
참고 사이트
'프로그래밍 > C++' 카테고리의 다른 글
C++ 소켓 프로그래밍(Socket Programming) 에코 클라이언트 (0) | 2024.07.31 |
---|---|
C++ 소켓 프로그래밍(Socket Programming) 에코 서버 (0) | 2024.07.31 |
C++ puts() vs printf() 차이점에 대해서 알아보자 (0) | 2024.07.25 |
htons(), htonl() 함수에 대해서 (8) | 2023.08.14 |
C++ MAKEWORD에 대해서 (2) | 2023.08.14 |
댓글