순수한 가상 방법 대 기능 포인터
-
20-08-2019 - |
문제
최근에 나는 스레드 클래스 라이브러리를 설계 해 왔으며 다음과 같은 스레드 추상 클래스를 만들었습니다.
class Thread {
public:
run() { /*start the thread*/ }
kill() { /*stop the thread*/ }
protected:
virtual int doOperation(unsigned int, void *) = 0;
};
실제 스레드 클래스는이 추상 클래스를 상속하고 구현합니다. doOperation
자체 논리의 방법, 비슷한 방법 전략 패턴.
문제는 다음 기능에서 스레드를 실행하는 것을 정의하는 C 백엔드 라이브러리에 의존한다는 것입니다.
int startThread(char* name, (int)(*)(unsigned int, void*), int, int, int, void*);
보시다시피; 두 번째 매개 변수는 스레드의 루프 (기본 함수)에 대한 함수 포인터이며 여기에 문제가 있습니다. 이 c- 기능을 사용하여 스레드를 시작하기 때문에 run
방법, 주소를 전달합니다 doOperation
두 번째 매개 변수로, 유형 불일치로 인해이를 수행 할 수 없습니다.
나는 사용하려고 노력했다 reinterpret_cast
포인터를 반환하려면, I ISO-C ++는 이니셜 화 된 기능 멤버의 포인터를 반환하는 것을 금지합니다. 정적 방법을 사용 하여이 갈등을 극복하는 방법을 모르겠습니다. 제가 생각하는 유일한 해결책이지만 디자인 패턴을 날려 버립니다!
해결책
먼저 좋은 정보가 포함되어 있으므로 Michael Burr가 제공 한 링크를 읽으십시오. 그런 다음 여기에 C ++ ISH 의사 코드가 있습니다.
int wrapperDoOperation(int v, void *ctx)
{
Thread *thread = (Thread *)ctx;
return thread->doOperation(v);
}
class Thread {
public:
run() {
startThread("bla", wrapperDoOperation, bla, bla, bla, (void *)this);
}
kill() { /*stop the thread*/ }
protected:
virtual int doOperation(unsigned int) = 0;
friend wrapperDoOperation ......;
};
아이디어는 스레드의 구성원 기능 인 DOOPERATION이 무효 *컨텍스트가 필요하지 않으며, 객체 자체의 컨텍스트로 전달할 모든 것을 유지할 수 있다는 것입니다. 따라서 공허 포인터를 사용 하여이 포인터를 Dooperation으로 전달할 수 있습니다. 공허 * 세부 사항은 수업 사용자에게 숨겨져 있습니다.