[c++] C ++의 콜백 함수



Answers

또한 콜백을 수행하는 C 방식이 있습니다 : 함수 포인터

//Define a type for the callback signature,
//it is not necessary, but makes life easier

//Function pointer called CallbackType that takes a float
//and returns an int
typedef int (*CallbackType)(float);  


void DoWork(CallbackType callback)
{
  float variable = 0.0f;

  //Do calculations

  //Call the callback with the variable, and retrieve the
  //result
  int result = callback(variable);

  //Do something with the result
}

int SomeCallback(float variable)
{
  int result;

  //Interpret variable

  return result;
}

int main(int argc, char ** argv)
{
  //Pass in SomeCallback to the DoWork
  DoWork(&SomeCallback);
}

이제 클래스 메소드를 콜백으로 전달하려는 경우 해당 함수 포인터에 대한 선언은보다 복잡한 선언을 갖습니다. 예를 들면 다음과 같습니다.

//Declaration:
typedef int (ClassName::*CallbackType)(float);

//This method performs work using an object instance
void DoWorkObject(CallbackType callback)
{
  //Class instance to invoke it through
  ClassName objectInstance;

  //Invocation
  int result = (objectInstance.*callback)(1.0f);
}

//This method performs work using an object pointer
void DoWorkPointer(CallbackType callback)
{
  //Class pointer to invoke it through
  ClassName * pointerInstance;

  //Invocation
  int result = (pointerInstance->*callback)(1.0f);
}

int main(int argc, char ** argv)
{
  //Pass in SomeCallback to the DoWork
  DoWorkObject(&ClassName::Method);
  DoWorkPointer(&ClassName::Method);
}
Question

C ++에서는 언제, 어떻게 콜백 함수를 사용합니까?

편집하다:
나는 콜백 함수를 작성하는 간단한 예제를보고 싶다.




콜백 함수가 다른 함수로 넘겨지고 어떤 시점에서이 함수가 호출되는 위의 정의를 참조하십시오.

C ++에서는 콜백 함수가 클래스 메소드를 호출하는 것이 바람직합니다. 이렇게하면 회원 데이터에 액세스 할 수 있습니다. 콜백을 정의하는 C 방식을 사용하는 경우 정적 멤버 함수를 가리켜 야합니다. 이것은 그리 바람직하지 않습니다.

다음은 C ++에서 콜백을 사용하는 방법입니다. 4 파일을 가정하십시오. 각 클래스에 대한 .CPP / .H 파일 쌍. 클래스 C1은 콜백 할 메소드가있는 클래스입니다. C2는 C1의 메소드를 다시 호출합니다. 이 예제에서 콜백 함수는 독자를 위해 추가 한 1 개의 매개 변수를 사용합니다. 이 예제에는 인스턴스화되고 사용되는 오브젝트가 표시되지 않습니다. 이 구현의 한 가지 유스 케이스는 데이터를 읽고 임시 공간에 저장하는 클래스와 포스트가 데이터를 처리하는 클래스가있는 경우입니다. 콜백 함수를 사용하면 읽은 모든 데이터 행에 대해 콜백이 처리 할 수 ​​있습니다. 이 기술은 필요한 임시 공간의 오버 헤드를 제거합니다. 후 처리해야하는 대량의 데이터를 반환하는 SQL 쿼리에 특히 유용합니다.

/////////////////////////////////////////////////////////////////////
// C1 H file

class C1
{
    public:
    C1() {};
    ~C1() {};
    void CALLBACK F1(int i);
};

/////////////////////////////////////////////////////////////////////
// C1 CPP file

void CALLBACK C1::F1(int i)
{
// Do stuff with C1, its methods and data, and even do stuff with the passed in parameter
}

/////////////////////////////////////////////////////////////////////
// C2 H File

class C1; // Forward declaration

class C2
{
    typedef void (CALLBACK C1::* pfnCallBack)(int i);
public:
    C2() {};
    ~C2() {};

    void Fn(C1 * pThat,pfnCallBack pFn);
};

/////////////////////////////////////////////////////////////////////
// C2 CPP File

void C2::Fn(C1 * pThat,pfnCallBack pFn)
{
    // Call a non-static method in C1
    int i = 1;
    (pThat->*pFn)(i);
}



콜백 함수 는 루틴으로 전달 된 메소드이며, 전달 된 루틴에 의해 어느 시점에서 호출됩니다.

이것은 재사용 가능한 소프트웨어를 만드는 데 매우 유용합니다. 예를 들어 많은 운영 체제 API (예 : Windows API)는 콜백을 많이 사용합니다.

예를 들어 폴더에있는 파일을 사용하여 작업하고 싶다면 자신의 루틴으로 API 함수를 호출 할 수 있으며 루틴은 지정된 폴더에서 파일 당 한 번 실행됩니다. 이렇게하면 API를 매우 유연하게 사용할 수 있습니다.




대답은 매우 유용하고 포괄적입니다. 그러나 OP 상태

나는 콜백 함수를 작성하는 간단한 예제 를보고 싶다.

그래서 여기에 C ++ 11에서 std::function 을 가지고 있으므로 함수 포인터와 비슷한 것들이 필요 없습니다 :

#include <functional>
#include <string>
#include <iostream>

void print_hashes(std::function<int (const std::string&)> hash_calculator) {
    std::string strings_to_hash[] = {"you", "saved", "my", "day"};
    for(auto s : strings_to_hash)
        std::cout << s << ":" << hash_calculator(s) << std::endl;    
}

int main() {
    print_hashes( [](const std::string& str) {   /** lambda expression */
        int result = 0;
        for (int i = 0; i < str.length(); i++)
            result += pow(31, i) * str.at(i);
        return result;
    });
    return 0;
}

이 예제는 어떻게 든 실제적입니다. 왜냐하면 당신은 print_hashes 다른 구현으로 function print_hashes 를 호출하기를 원하기 때문에이 목적을 위해 간단한 것을 제공했습니다. 그것은 문자열을 받고 int (제공된 문자열의 해시 값)를 반환하며 구문 부분에서 기억해야하는 것은 std::function<int (const std::string&)> 입니다. 그것을 호출 할 함수의 인수를 입력하십시오.




Links