void*와 멤버 함수에 대한 포인터 사이의 캐스팅
C 프로그래밍 세계에서 void*와 멤버 함수에 대한 포인터 사이의 캐스팅 멤버 함수는 정말 골치 아픈 일이 될 수 있습니다. 이 문제를 설명하는 특정 문제를 살펴보겠습니다.
다음 코드 조각을 고려하세요.
<code class="cpp">template <class T> int call_int_function(lua_State *L) { void (T::*method)(int, int) = reinterpret_cast<void (T::*)(int, int)>(lua_touserdata(L, lua_upvalueindex(1))); // <-- problematic line T *obj = reinterpret_cast<T *>(lua_touserdata(L, 1)); (obj->*method)(lua_tointeger(L, 2), lua_tointeger(L, 3)); return 0; }</code>
여기서 GCC는 void*에서 void(T::*)로의 캐스트에 대해 불평합니다. (int, int)가 유효하지 않습니다. 그렇다면 해결책은 무엇입니까?
문제 이해
문제를 이해하려면 멤버 함수에 대한 포인터의 특성을 더 깊이 파고들어야 합니다. 주소를 가리키는 일반 포인터와 달리 멤버 함수에 대한 포인터는 훨씬 더 복잡합니다. 여기에는 컴파일러 구현 및 클래스 멤버의 레이아웃과 관련된 정보가 포함되어 있습니다.
대체 접근 방식
사실 void*를 포인터에 직접 캐스팅할 수는 없습니다. 멤버 함수에. 제안된 솔루션은 멤버 함수를 일반 함수로 래핑하고 대신 반환하는 것입니다. 방법은 다음과 같습니다.
<code class="cpp">template <class T> int call_int_function(lua_State *L) { void (*method)(T*, int, int) = reinterpret_cast<void (*)(T*, int, int)>(lua_touserdata(L, lua_upvalueindex(1))); T *obj = reinterpret_cast<T *>(lua_touserdata(L, 1)); method(obj, lua_tointeger(L, 2), lua_tointeger(L, 3)); return 0; }</code>
이제 void*에 저장하고 문제 없이 검색할 수 있는 일반 함수 포인터로 캐스팅하고 있기 때문에 이 접근 방식이 효과적입니다.
위 내용은 C에서 'void*'와 멤버 함수에 대한 포인터 사이를 안전하게 캐스팅하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!