본문 바로가기
Script/C++

[C++] Chapter 07. 함수 객체

by song.ift 2023. 5. 12.

함수 객체 (Functor) : 함수처럼 동작하는 객체

함수 포인터의 단점

완전히 동일한 시그니처로 만들어진 함수만 들고있을 수 있지만, 함수 객체를 사용하면 어느 정도 극복 가능

  1. 시그니처가 안 맞으면 사용할 수 없다.
  2. 상태를 가질 수 없다. (멤버를 가질 수 없어서 경우에 따라서 기존에 실행했던 또는 저장했던 데이터를 유지시키고 싶지만 그럴 수 없다.)

 

[함수처럼 동작]하는 객체

그래서 () 연산자 오버로딩이 필요하다

class Functor
{
    public:
        void operator()()
        {
            cout << hp << endl;
        }

        bool operator()(int num)
        {
            cout << "Test" << endl;
            hp += num;
        }

    private:
        int hp = 100;
}

int main()
{
    Functor functor;

    functor();
    bool ref = functor(3);
}

함수 포인터와 다르게 상태값도 가지면서, 일반 함수처럼 호출도 할 수 있다.

함수 포인터는 시그니처가 일치하는 딱 하나의 함수만 대입할 수 있으면, 함수 객체는 여러가지 시그니쳐로 다양하게 응용할 수 있다.

 

MMO에서 함수 객체를 사용하는 예시

서버 : 클라가 보내준 네트워크 패킷을 받아서 처리

ex) 클라 : 나 (5, 0) 좌표로 이동시켜줘

함수 객체를 사용하면 함수 객체를 만들어주는 시점과 실제 실행하는 시점을 분리할 수 있음.

class MoveTask
{
    public:
        void operator()()
        {

        }

    public:
        int _playerId;
        int _posX;
        int _posY;
}

int main()
{
    MoveTask task;
    task._playerId = 100;
    task._posX = 5;

    // 나중에 여유될 때 일감을 실행한다
    task();
}

 

💡 근데 위의 특징을 보면 함수포인터는 좋은데 함수 객체는 굳이 왜 쓰는가? Knight 클래스 같은걸로 바로 플레이어의 좌표를 이동시키면 되는데?

사실 함수 객체의 개념과 유사하다. 함수(기능) + 객체(데이터) 을 동시에 갖고 있는 것이다.
물론 Knight 객체를 바로 사용하면 되지, 굳이 따로 함수 객체를 만들 필요가 있을까 싶지만, 게임에서 User 객체 (Knight 객체)는 엄청 사이즈가 커질 수 있다.
정말 딱 필요한게 이동함수 + 좌표2개라면, 게다가 심지어 해당 기능이 Knight와 무관하다면 별도의 클래스를 파는게 훨 낫다

댓글