- Curiously Recurring Template Pattern(신기하게도 언급되는 템플릿 패턴)
class Base
{
// Base에서는 Derived의 이름을 알 수 없다.
// 알게 하고 싶다면?? -> CRTP
};
class Derived : public Base
{
};
int main()
{
Derived d;
}
template<typename T> class Base
{
public:
Base()
{
cout << typeid(T).name() << endl;
}
};
class Derived : public Base<Derived> // 파생클래스를 만들때 이름을 전달해준다.
{
};
int main()
{
Derived d;
}
어디에 쓰면 좋을까?
#include <iostream>
using namespace std;
class Window
{
public:
void msgLoop()
{
OnClick();
}
void OnClick() { cout << "Window OnClick" << endl; }
};
class FrameWindow : public Window
{
public:
void OnClick() { cout << "FrameWindow Window OnClick" << endl; }
};
int main()
{
FrameWindow fw;
fw.msgLoop(); // Window::OnClick가 호출된다
// 원하는 것은 FrameWindow::OnClick 호출되는 것
// 물론 virtual선언하면 되지만 ... 오버헤드가 커진다.
}
template<typename T> class Window
{
public:
void msgLoop()
{
//OnClick();
static_cast<T*>(this)->OnClick();
}
void OnClick() { cout << "Window OnClick" << endl; }
};
class FrameWindow : public Window<FrameWindow>
{
public:
void OnClick() { cout << "FrameWindow Window OnClick" << endl; }
};
Example - CRTP를 이용해서 singleton 만들어보자.
class Cursor
{
private:
Cursor() {}
public:
Cursor(const Cursor& c) = delete;
void operator=(const Cursor& c) = delete;
static Cursor& getInstance()
{
static Cursor instance;
return instance;
}
};
int main()
{
// Cursor c1, c2;
Cursor& c1 = Cursor::getInstance();
Cursor& c2 = Cursor::getInstance();
// 같음
}
class Mouse
{
// Mouse도 Singleton화 하고 싶다면?
};
class Mouse : public Singleton // 이렇게?
{
};
template<typename T> class Singleton
{
protected:
Singleton() {}
public:
Singleton(const Singleton& c) = delete;
void operator=(const Singleton& c) = delete;
static T& getInstance()
{
static T instance;
return instance;
}
};
class Mouse : public Singleton<Mouse>
{
};
int main()
{
Mouse& m = Mouse::getInstance();
}
Example
#include <iostream>
using namespace std;
class Object
{
public:
static int cnt;
Object() { ++cnt; }
~Object() { --cnt; }
static int getCount() { return cnt; }
};
int Object::cnt = 0;
class Mouse
{
// Mouse에서도 객체의 개수를 관리하고 싶다면??
};
int main()
{
Object c1, c2;
cout << c1.getCount() << endl;
}
class Mouse : Object
{
};
class Keyboard : Object
{
};
int main()
{
Mouse m1, m2;
Keyboard k1, k2;
cout << m1.getCount(); << endl; // 4 -> 잉??
}
template<typename T> class Object
{
public:
static int cnt;
Object() { ++cnt; }
~Object() { --cnt; }
static int getCount() { return cnt; }
};
template<typename T> int Object::cnt = 0;
class Mouse : Object<Mouse>
{
};
class Keyboard : Object<Keyboard>
{
};
int main()
{
Mouse m1, m2;
Keyboard k1, k2;
cout << m1.getCount(); << endl; // 2
}