• English

c++ class callback 함수 예제

Java는 템플릿과 유사하지 않으므로 이 모든 것에 대해 동적 바인딩을 사용해야 하며 필요성의 동적 바인딩은 함수 호출을 의미합니다. 일반적으로 큰 문제가 아니지만 C ++에서는 매우 높은 성능의 코드를 사용하려고합니다. 즉, C++는 “사용한 경우에만 지불”이라는 철학을 가지고 있는데, 이는 언어가 물리적 컴퓨터가 수행할 수 있는 것에 대해 임의로 오버헤드를 부과해서는 안 된다는 것을 의미합니다(물론 프로그래머는 선택적으로 동적 바인딩과 같은 기술을 사용할 수 있습니다. 일반적으로 유연성이나 다른 “일리티”에 대한 대가로 약간의 오버 헤드를 부과하지만 디자이너와 프로그래머는 이러한 구문의 이점 (및 비용)을 원하는지 여부를 결정해야합니다. 때로는 사람들이 이러한 함수 포인터의 배열을 만듭니다: 긴 대답: C++에서 멤버 함수에는 개체를 가리키는 암시적 매개 변수가 있습니다(멤버 함수 내의 이 포인터). 일반 C 함수는 멤버 함수와 다른 호출 규칙을 갖는 것으로 생각할 수 있으므로 포인터 유형(포인터 대 멤버 함수 vs 포인터-함수)은 서로 다르며 호환되지 않습니다. C++는 개체를 제공해야만 호출할 수 있는 포인터-멤버라는 새로운 유형의 포인터를 도입합니다. 참고: 정적 멤버 함수는 실제 개체를 호출할 필요가 없으므로 포인터-정적-멤버-함수는 일반적으로 일반 포인터-함수와 형식 호환됩니다. 그러나 대부분의 컴파일러에서 작동하지만 실제로는 “C linkage”가 이름 mangling과 같은 것뿐만 아니라 C와 C + 간에 다를 수 있는 호출 규칙을 다루지 않으므로 실제로는 외형 “C” 비멤버 함수가 정확해야 합니다. +.

이는 API의 동작 또는 결과가 인수로 전달된 콜백에 종속된다는 것을 보여줍니다. 다음 예제는 이전 FAQ의 예와 비슷합니다. doit()을 연산자()()로 변경하여 호출자의 가독성을 높이고 누군가가 일반 함수 포인터를 전달할 수 있도록 했습니다. 참고: 포인터-멤버-함수를 포인터-함수로 “캐스팅”하려고 시도하지 마십시오. 결과는 정의되지 않았으며 아마도 재앙일 것입니다. 예를 들어, 포인터-멤버-함수는 적절한 함수의 기계 주소를 포함할 필요가 없습니다. 마지막 예제에서 말했듯이 일반 C 함수에 대한 포인터가 있는 경우 최상위(비멤버) 함수 또는 정적(클래스) 멤버 함수를 사용합니다. 위의 함수의 경우 func1을 선언하여 함수에 대한 포인터를 가져 와서 런타임에 func2의 주소를 전달합니다. typedef를 사용하여 지저분한 구문을 더 쉽게 읽고 디버깅할 수 있습니다. 예제 15-1은 함수 포인터를 사용하여 콜백 함수를 구현하는 방법을 보여 주며 있습니다.

따라서 사용자가 이러한 함수 중 하나에서 doit()을 호출할 때 “남은” args를 공급하고 호출은 개념적으로 ctor에 전달된 원래 아르그와 doit() 메서드에 전달된 것과 결합합니다: 옆: 위의 첫 번째 단락에서 암시된 대로 , 일반 함수의 이름을 전달할 수도 있습니다 (호출자에서 사용할 때 함수 호출 비용이 발생할 수 있음) 지금까지 함수 포인터를 콜백으로 사용하는 방법을 보았습니다. 그러나 이 접근 방식과 이전 FAQ의 방법의 차이점은 fuctionoid가 런타임이 아닌 컴파일 타임에 호출자에게 “바인딩”된다는 것입니다. 매개 변수에 전달으로 생각 : 당신이 컴파일 타임에 당신이 궁극적으로 전달하려는 함수의 종류를 알고 있다면, 당신은 위의 기술을 사용할 수 있습니다, 당신은 적어도 일반적인 경우에, 컴파일러 인라인 확장을 갖는 속도 이점을 얻을 수 있습니다 호출자 내의 함수코드 코드입니다. 여기에 예입니다 : 함수를 사용하면 상황이 적어도 때로는 훨씬 낫습니다. 함수는 동결 건조 함수 호출로 생각할 수 있기 때문에 y 및 / 또는 z라고 부르는 것과 같이 일반적인 args를 가져 와서 해당 ctors로 만듭니다. 당신은 또한 일반적인 args (이 경우 int라는 x)를 ctor에 전달할 수 있지만 대신 순수한 가상 doit() 메서드에 전달할 수있는 옵션이 있습니다.