STL std::function 기반 콜백함수 구현

2015. 10. 20. 15:08IT-개발/STL 및 Boost

반응형

 


 개요 


 통상 콜백함수 구현시  함수포인터 기반으로 구현하는 방식 (보기 -> http://igotit.tistory.com/212 ) 으로는 클래스 멤버함수를 콜백으로 등록하지 못하는 단점이 있다.

 

STL (Standard Template Library) 에서 제공하는 std::function, std::bind 등을 사용하면 클래스 멤버함수도 콜백함수로 등록가능하므로 대단히 편리하다.



 STL 기반 콜백구현방법


아래 설명방식에서 "다른 곳", "이곳" 이란 표현은 함수포인터 기반 콜백구현방법 설명글 (http://igotit.tistory.com/212 )에서의 것과 동일한 것임.

 

 "이곳"에 있는 함수(클래스의 멤버함수도 가능하다.)를 다른곳(예.  다른 클래스 개체, DLL등 )에 전달하여 다른 곳에서 "이곳"의 클래스 멤버 함수를 호출하는 법에 대한 STL 기반 코딩 골격을 정리한다. 

 

 

"다른 곳" 코딩. - 아래 파란색 부분이 STL기반 구현부분 핵심에 해당함.

 

#include <functional> // std::functional 등을 사용하기 위하여 포함함.

 

typedef std::function<int(int)> pFunc; // pFunc 이라는 타입선언. 이것은 함수포인터 방식에서의 typedef int(*pFunc)(int); 에 해당함.

 

pFunc your_func;          // "이 곳"의 함수를 받을 변수선언이다. 함수포인터 방식에서와 동일함. 

 

//"이 곳"의 함수포인터로 인자를 전달하면 your_func 으로 대입해 줄 함수.

void regi_func(pFunc p_func)

{

  your_func = std::move(p_func);  

//인자로 전달받은 함수포인터를 your_func 으로 받는다.함수포인터방식에서your_func = p_func에 해당.

// (추가한 내용)

// "your_func" 처럼 직접 호출할 함수 pointer 변수에 저장할 때에만 std::move 사용하면 된다. 중간에 함수 파라미터로 값을 계속 전달할 때에는 pFunc p_func 이런식으로 계속 전달하면 됨.

}

//

void exec_func()

{

 your_func(1);  // regi_func 의 인자로 전달된 함수가 실행되는 것임.

}

 

"이곳 " 코딩.

이곳에는 int Function(int a) {... } 함수 클래스 ThisClass 의 멤버함수로 정의되어있다고 치자. 클래스 멤버함수를 "다른 곳" 의 regi_func 을 호출하면서 함수포인터를 전달한다.

regi_func(std::bind(&ThisClass::Function, this, std::placeholders::_1));

 

// 클래스멤버함수 전달시 std::bind 를 사용한다는 점. 클래스의 this 개체 전달한다는 점, 클래스 멤버함수의 인자 1개 있다는점을 표현한것이다. 비교 : 함수포인터 방식에서는 regi_func(Function); 으로 했었다.

std::placeholder 관련처리 상세.

우리가 정의한 콜백함수 Function 에 만일 인자가 없다면 기록하지 않으면 된다. 만일 인자가 3개라면 즉 Function(int a, float b, char c) 라면

위 등록함수는 아래처럼 인자수량만큼 추가하면 된다.

regi_func(std::bind(&ThisClass::Function, this, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3));

 

 

결론.

위와 같이 설정해두면 , "다른곳" 의 exec_func() 이 실행되면 "이곳"의 클래스 멤버함수인 Function 이 실행된다.

 

위 방식이 STL 기반 콜백함수 구현의 골격 전부이다. 이 방식으로 클래스 멤버함수도 간단히 콜백함수로 전달가능하여 콜백함수내에서 클래스 멤버에 접근이 용이하고 코드 구조도 간결해지는 큰 장점이 있다.