이번에도 멤버함수 실습과 관련해서
타이머 제작을 해볼게요
#include <iostream>
#include "ecourse.hpp"
using namespace std;
using namespace ecourse;
void foo(int id)
{
cout<< "foo : "<< id << endl;
}
int main()
{
int n1 = ec_set_timer(500,foo);
ec_process_message();
}
위에는 간단한타이머인데요 500밀리세컨드마다 foo함수가 호출되는 타이머이죠
하지만 위 코드는 C스타일이죠
그럼 객체지향 스타일로 만들어볼까요
#include <iostream>
#include "ecourse.hpp"
#include <map>
using namespace std;
using namespace ecourse;
class Clock
{
static map<int,Clock*> this_map;
string name;
public:
Clock(string n) : name(n){}
void Start(int ms)
{
int id = ec_set_timer(ms,TimerHandler); //패러미터가 ID 하나야만 가능
this_map[id] = this;
}
//this 포인터를 없애기위해 스택함수로 수정
static void TimerHandler(int id)
{
cout << this_map[id]->name <<endl; //this->name
}
};
map<int,Clock*> Clock::this_map;
int main()
{
Clock c1("A");
Clock c2("\tB");
c1.Start(1000);
c2.Start(500);
ec_process_message();
}
간단히 Clock 클래스를 만들고 Start함수안에서 타이머를 시작하려는데
함수포인터를 넘기는 함수가 멤버 함수라 이전과 같이 const this* 가 숨겨져 있어 에러가 납니다.
이전에는 스레드의 패러미터로 넘겼지만 이번 경우에는 패러미터로 넘길 수도 없죠...
어떻게 하면될까요!
이런 경우 this 포인터를 자료구조에 저장하여 넘겨주는 방법이 있습니다.
위에 Start함수와 TimerHandler함수의 공통적으로 있는 값이 무엇일까요
바로 타이머 ID입니다.
이 ID 를 key로 하여 hash인 map 자료구조에 넣어준후 TimerHandler에서 패러미터로 받은 ID를 통해 해당 클래스 this포인터에 접근이 가능합니다!!
신박하죠?
이런 방법은 아주 유명한 방법이라고 합니다.
정말 똑똑한 사람이 많습니다.
map은 전역으로 선언해도되지만 클래스에 스태틱으로 만드는게 더 깔끔하겠죠
모처럼 놀라운 테크닉이었습니다.
감삽니다.
'프로그램-잉 > C++' 카테고리의 다른 글
스레드 만들기 (0) | 2020.10.29 |
---|---|
멤버함수 포인터 (0) | 2020.10.27 |
[C++] Method Call (0) | 2020.10.26 |
VS Code C++ 17 사용법 (0) | 2020.10.25 |
VS Code에서 Boost Library 사용법 (0) | 2020.10.24 |