콜백함수 예제 c++

비정적 멤버에 대한 포인터는 전달할 클래스 개체의 이 포인터가 필요하므로 일반 C 함수 포인터와 다릅니다. 따라서 일반 함수 포인터와 비정적 멤버 함수에는 서로 다른 호환되지 않는 시그니처가 있습니다! 특정 클래스의 멤버로 콜백하려는 경우 일반 함수 포인터에서 멤버 함수에 대한 포인터로 코드를 변경하면 됩니다. 그러나 임의의 클래스의 비정적 멤버로 콜백하려면 어떻게 해야 할까요? 그것은 조금 어렵다. 정적 멤버 함수를 래퍼로 작성해야 합니다. 정적 멤버 함수에는 C 함수와 동일한 서명이 있습니다! 그런 다음 멤버 함수를 void*로 호출하려는 개체에 포인터를 캐스팅하고 추가 인수 또는 전역 변수를 통해 래퍼에 전달합니다. 전역 변수를 사용하는 경우 항상 올바른 개체를 가리키는지 확인하는 것이 매우 중요합니다. 물론 멤버 함수에 대한 호출 인수를 통과해야합니다. 래퍼는 void 포인터를 해당 클래스의 인스턴스에 대한 포인터에 캐스팅하고 멤버 함수를 호출합니다. 아래에서 두 가지 예를 찾을 수 있습니다. 여기서 멤버 함수에 대한 명명된 포인터는 함수 포인터와 유사하게 다음과 같습니다: 예를 들어 폴더에 있는 파일로 작업하려는 경우 자신의 루틴으로 API 함수를 호출할 수 있으며 루틴은 지정된 폴더의 파일당 한 번 실행됩니다.

. 이렇게 하면 API가 매우 유연해질 수 있습니다. C ++ 코드에서 사용하기 위해 이것은 상당히 번거로운 방법입니다. 모든 콜백에 대해 정적 함수와 실제 콜백 함수의 두 가지 함수를 정의해야 합니다. 콜백에 함수 포인터를 사용하는 C 코드와 인터페이싱할 때 이 방법은 완벽한 방법입니다. 그것은 성공적으로 C에서 C ++로 점프합니다. 콜백 기능은 여러 가지 다른 것들이 호출 할 수 밝혀때문에 C ++(11)에서 여러 가지 방법으로 실현 될 수 있습니다 *: 나는 리치 히키의 템플릿 functor 콜백 접근 방식이 C ++11의 람다 함수보다 약간 낫다고 말할 것입니다. 이상적인 솔루션에 더 직접적이고 가깝습니다.

또한 C++11 이전 컴파일러에서도 작동합니다. 나는 몇 년 동안 이것을 사용하고 그것을 추천했다. 콜백 함수는 C 표준의 일부이므로 C++의 일부이기도 합니다. 그러나 C ++로 작업하는 경우 관찰자 패턴을 대신 사용하는 것이 좋습니다: http://en.wikipedia.org/wiki/Observer_pattern C에서 콜백 함수는 함수 포인터를 통해 호출되는 함수입니다. 이 암호화 함수는 문자열의 모든 문자를 1씩 증가시입니다. 템플릿 Functors (리치 히키 1994)를 사용하여 C ++ 콜백 – 인터페이스 클래스 접근 방식 (Callee Mix-In) 및 함수 포인터 접근 방식 (함수 모델)을 다룹니다. 지금까지 함수 포인터를 콜백으로 사용하는 방법을 보았습니다. 그러나 호출 가능한 을 저장하는 std:::function 개체의 유형은 다음과 같습니다: 콜백은 두 클래스를 분리해야 하지만 단일 함수 호출을 통해 연결해야 할 때 개체 지향 디자인에 대단히 유용합니다. 예제가 풍부하고 어느 시점에서 확장하겠습니다.

지금은 C++에서 콜백을 구현하는 다양한 접근 방식으로 실험을 계속할 수 있는 장소입니다. 호출 표기법은 간단한 함수 호출 구문을 따릅니다: 매 초, 타이머 개체 t는 연결된 콜백 함수 myObject.foo()를 호출합니다. main()에서는 람다로 연결이 이루어지는 것을 볼 수 있습니다. C 함수 포인터 접근 방식의 정적 함수와 마찬가지로 lambda는 클래스에 들어갈 수 있도록 « this » 포인터를 캡처합니다. 람다 구문은 약간 둔감합니다. 이것은 아마도이 접근 방식의 유일한 단점입니다. C++에서는 콜백 함수가 클래스 메서드를 호출하도록 하는 것이 바람직합니다. 이렇게 하면 멤버 데이터에 액세스할 수 있습니다. 콜백을 정의하는 C 방법을 사용하는 경우 정적 멤버 함수를 가리킬 수 있습니다. 이것은 매우 바람직하지 않습니다. 그래서 여기 C ++11에서 std::function이 있으므로 함수 포인터 및 이와 유사한 것들이 필요하지 않습니다 : C 및 C ++는 콜백 함수를 구현하는 데 필요한 모든 것을 갖습니다.