c++ delegate 예제

lambda 인스턴스를 대리자 인스턴스에 전달할 때 가장 중요한 문제는 주요 람다, 클로저 캡처의 지원입니다. 특히 lambda 인스턴스를 값으로 복사할 때 이 기능이 손실됩니다(캡처 집합이 비어 있지 않으면 복사본이 호출시 예외를 throw합니다). 나에게 이러한 람다 디자인은 의심스럽지만 이것은 표준 동작입니다. 호출자에서 만든 포인터로 인스턴스를 전달하는 것은 작동하지만 null 포인터를 처리해야하기 때문에 실행 가능한 디자인이 될 수 없습니다. 따라서 유일한 합리적인 해결책은 팩터리 함수 내부의 포인터를 상수 참조및 생성하여 lambda 인스턴스를 전달하는 것입니다. 여기에 표시된 처리기는 lambda 식에서 만든 대리자 템플릿 클래스의 인스턴스입니다. std::function을 기반으로 하는 처리기의 또 다른 형식이 있습니다. 흥미롭게도 컨텍스트에서 컴파일러에서 처리기 형식을 추론(추론)할 수 있기 때문에 함수 템플릿 인스턴스화는 필요하지 않습니다. 당신은 아마 발견 – 대리자의 선언은 꽤 상세합니다. 단순화할 수 있습니까? 나는 매크로와 템플릿 마법으로 할 수 있다고 생각하지만, 나는 도우미 클래스를 선호합니다.

이 클래스는 대리자 추가 및 제거를 처리합니다. 나는 그것을 호출 – 디스패처. 추상 버튼 클래스를 상상해 보십시오. 예를 들어 클릭과 같은 일부 이벤트에 대한 디스패처가 있을 수 있습니다. 이제 이 클릭 이벤트를 수신하려는 모든 엔터티가 이 디스패처에 대리자를 추가할 수 있습니다. 그리고 실제 이벤트가 트리거되면 이 디스패처는 추가된 모든 콜백을 호출합니다. 다음은 간단한 구현입니다. 나는 인터넷 검색에 의해 마지막 기사를 발견 « C ++ 대리자 ». 저자의 첫 번째 관심사는 성능대신 단순성이었기 때문에 샘플 코드 측면에서 가장 쉽고 필요한 것이었습니다.

그는 다형성을 사용하여 함수 포인터와 멤버 함수 포인터를 다르게 처리했습니다. 그의 샘플 코드는 내 자신의 대리자 클래스 디자인을 가장 많이 구상하는 데 도움이되었습니다. 하지만 기사를 읽는 것이 어려웠기 때문에 기사를 읽지 않았습니다. 좀 더 유연하지만, 우리는 여전히 진정한 일반적인 대리자 구현을 목표로 하고 있지 않습니다. 이 샘플은 속성의 접근자 함수에 대한 언바운드 대리자를 만듭니다: 모듈식 프로그래밍을 좋아합니다. 그러나 모듈은 어떻게 든 서로 통신해야합니다. 콜백을 서로 전달할 수 있지만 이 경우 C++의 멤버 함수에 대한 포인터는 다음과 같이 보입니다. 함수.

우리가 갖고 싶은 것은 반환 값과 인수 형식의 가능한 모든 조합에 대한 대리자입니다. 전문 대리자는 템플릿 std::function과 유사하게 템플릿 인스턴스화를 위한 편리한 프로필을 만듭니다: Sergey는 « 대리자 메서드에 대한 포인터가 포함되어 있지 않습니다 »라고 주장했습니다. 하지만 왜? 실제로 이러한 포인터를 포함하지만 이 포인터만 런타임 동안 대리자 인스턴스에 전달되지 않습니다. 대신 모든 템플릿 인스턴스화는 모든 메서드 주소를 즉시 상수 형태로 생성하므로 이러한 포인터의 비교는 서로 다른 스텁의 비교를 통해 정확하지만 간접적으로 수행됩니다. 두 스텁 포인터가 다른 경우 기본 함수 포인터가 다르고 그 반대의 경우도 마찬가지입니다. 대리자를 눈에 좀 더 기쁘게 만들기 위해 할 수 있는 일을 살펴보겠습니다: 작업의 좋은 부분이 제품 수명 시간의 컴파일 타임 단계에 위임되기 때문에 메커니즘이 빠릅니다.

This entry was posted in Non classé. Bookmark the permalink.

Comments are closed.