개발/C, C++
C++ - 템플릿으로 클래스 상속하기 (Mixin Inheritance)
피로물든딸기
2024. 3. 6. 18:44
반응형
참고
- 데코레이터 패턴
클래스 CBA가 클래스 A, B, C의 모든 메서드를 사용하려면 상속을 받으면 된다.
class CBA : public A, public B, public C { };
예제 코드는 다음과 같다.
#include <iostream>
using namespace std;
class A
{
public:
void methodA() { cout << "Method A" << endl; }
};
class B
{
public:
void methodB() { cout << "Method B" << endl; }
};
class C
{
public:
void methodC() { cout << "Method C" << endl;}
};
class CBA : public A, public B, public C { };
int main()
{
CBA* cba = new CBA();
cba->methodA();
cba->methodB();
cba->methodC();
return 0;
}
Mixin Inheritance
템플릿 파라미터를 이용해서도 상속을 구현할 수 있다.
클래스 B와 C는 template을 이용하여 클래스 템플릿을 만들어 보자. (A는 변경사항 없음)
template<typename T>
class B : public T
{
public:
void methodB() { cout << "Method B" << endl; }
};
그러면 아래와 같이 클래스를 생성할 수 있다.
C<B<A>>* cba = new C<B<A>>();
cba는 마치 A, B, C를 상속한 것 처럼, A, B, C의 모든 메서드를 호출할 수 있다.
cba->methodA();
cba->methodB();
cba->methodC();
전체 코드는 다음과 같다.
#include <iostream>
using namespace std;
class A
{
public:
void methodA() { cout << "Method A" << endl; }
};
template<typename T>
class B : public T
{
public:
void methodB() { cout << "Method B" << endl; }
};
template<typename T>
class C : public T
{
public:
void methodC() { cout << "Method C" << endl; }
};
int main()
{
C<B<A>>* cba = new C<B<A>>();
cba->methodA();
cba->methodB();
cba->methodC();
return 0;
}
그리고 아래 코드에서 static 메서드로 getName을 추가해 보자.
데코레이터 패턴에서 클래스의 메서드를 동적으로 추가한 것과 같은 효과를 낼 수 있다.
#include <iostream>
#include <string>
using namespace std;
class A
{
public:
void methodA() { cout << "Method A" << endl; }
static string getName() { return "A"; }
};
template<typename T>
class B : public T
{
public:
void methodB() { cout << "Method B" << endl; }
static string getName() { return "B<" + T::getName() + ">" ; }
};
template<typename T>
class C : public T
{
public:
void methodC() { cout << "Method C" << endl; }
static string getName() { return "C<" + T::getName() + ">"; }
};
int main()
{
cout << "Class Name : " << C<B<A>>::getName() << endl;
cout << "Class Name : " << B<C<A>>::getName() << endl;
return 0;
}
반응형