//범용 함수 포인터의 설계
#include <iostream>
using namespace std;
// 함수 포인터 객체와 멤버 함수 포인터 객체를 모두 처리하기 위하여 부모 클래스를 설계
// 서로 다른 타입의을 하나의 타입으로 처리하려면 반드시 부모 클래스를 만들어야 한다.
struct ICommand {
virtual ~ICommand() {}
virtual void excute() = 0;
};
// 일반 함수 포인터를 저장하는 클래스를 설계
class FunctionCommand : public ICommand {
typedef void(*CALLBACK)();
CALLBACK handler;
public:
FunctionCommand(CALLBACK h) : handler(h) {}
void excute() { handler(); }
};
// 멤버 함수 포인터를 저장하는 클래스를 설계
template<typename T> class MemberCommand : public ICommand {
typedef void(T::*CALLBACK)();
T* pObject;
CALLBACK handler;
public:
MemberCommand(CALLBACK h, T *p) : pObject(p), handler(h) {}
void excute() { (pObject->*handler)(); }
};
// 일반 함수
void function() { cout << "::function()" << endl; }
class Dialog {
public:
// 멤버 함수
void function() { cout << "Dialog::function()" << endl; }
};
template<typename T> MemberCommand<T>* cmd(void(T::*handler)(), T* p) {
return new MemberCommand<T>(handler, p);
}
FunctionCommand* cmd(void(*handler)()) { return new FunctionCommand(handler); }
int main() {
//FunctionCommand fc(&function);
//fc.excute();
//FunctionCommand *p1=cmd(&function);
ICommand *p1=cmd(&function);
p1->excute();
Dialog dlg;
//MemberCommand<Dialog> mc(&Dialog::function, &dlg); //명시적 추론
//mc.excute();
//MemberCommand<Dialog>* p2=cmd(&Dialog::function, &dlg);
ICommand *p2=cmd(&Dialog::function, &dlg);
p2->excute();
}
<표준에서 제공하는 범용함수 포인터>
#include <iostream>
#include <functional>
using namespace std;
void foo() { cout << "foo()" << endl; }
void goo(int a) { cout << "goo(" << a <<")" << endl; }
class Dialog {
public:
void close() { cout << "Dialog::close" << endl; }
};
int main() {
function<void()> fp=&foo;
fp();
fp= bind(&goo, 3);
fp();
Dialog dlg;
fp=bind(&Dialog::close, &dlg);
fp();
return 0;
}
'Developer > Design Patterns' 카테고리의 다른 글
전략 패턴 (0) | 2014.05.18 |
---|---|
Template Method Pattern (0) | 2014.05.18 |
함수 포인터 기반의 이벤트 핸들링 기법 (0) | 2014.05.18 |
인터페이스 기반의 객체의 이벤트 처리 (0) | 2014.05.18 |
State Pattern (0) | 2014.05.18 |