함수처럼 동작하는 객체이다.
Function Object, 또는 Functor라고 불린다.
다르게 말하자면 객체(class 등)이 함수처럼 동작하도록 만들어주는 것이다.
이를 위해서는 operator()
연산자를 오버로딩하여 만들어 주어야 한다.
#include <iostream>
using namespace std;
class Functor
{
public:
void operator() ()
{
cout << "Functor Test" << endl;
cout << _value << endl;
}
private:
int _value = 0;
};
int main()
{
Functor functor;
// 함수 객체 호출
functor();
}
int _value=0;
과 같은 멤버 데이터operator()
를 오버로딩하여 쉽게 다른 시그니쳐를 만들어서 사용할 수 있다.#include<iostream>
#include<vector>
using namespace std;
// 요청서 클래스
class Command
{
public:
Command(int playerId, int posX, int posY)
: _playerId(playerId), _posX(posX), _posY(posY)
{ }
void Printer()
{
cout << "ID: " << _playerId << ", X: " << _posX << ", Y: " << _posY << endl;
}
private:
int _playerId;
int _posX;
int _posY;
};
// 요청들을 저장 및 실행할 클래스
class MoveTask
{
public:
void operator() ()
{
cout << "해당 좌표로 플레이어 이동" << endl;
for (auto cmd : commands)
cmd->Printer();
}
void AddRequest(Command* cmd)
{
commands.push_back(cmd);
}
private:
vector<Command*> commands;
};
int main()
{
// 함수 객체(Functor) : 함수처럼 동작하는 객체
// MMO에서 함수 객체를 활용하는 예시
// 클라 <-> 서버
// 서버 : 클라가 보내준 네트워크 패킷을 받아서 처리
// ex) 클라 : 나 (5,0) 좌표로 이동시켜줘!
// 함수 객체의 장점 : 만들어주는 시점과 실행하는 시점을 분리할 수 있다!
MoveTask task;
// 1) 요청
Command cmd1(1000, 5, 5);
Command cmd2(2000, 40, 10);
Command cmd3(3000, 20, -5);
// 무수히 많은 요청서들....
// 2) 저장
task.AddRequest(&cmd1);
task.AddRequest(&cmd2);
task.AddRequest(&cmd3);
// 3) 실행
// 여유가 생기면 요청들을 처리한다
task();
// 위와 같이 단계를 분리해줄 수 있겠다.
return 0;
}
해당 좌표로 플레이어 이동
ID: 1000, X: 5, Y: 5
ID: 2000, X: 40, Y: 10
ID: 3000, X: 20, Y: -5