2017-11-28 26 views
3

저는 명령과 컨트롤 유형 시나리오를 사용하여 함수 포인터를 자유롭게 사용했습니다. 여기서는 메시지가 의뢰. 이것은 switch-case (점프 테이블 최적화는 제쳐두고)을 사용하여 더 이상 그런 일을 할 필요가 없으므로 합리적으로 효율적인 구현을합니다. 대신이의C++에서 멤버 함수에 대한 함수 포인터의 배열 사용

: 예를 들어

switch(msg.cmd){ 
    case FUNC0: 
     return func0(msg); 

    case FUNC1: 
     return func1(msg); 

    ... 
} 

우리는 (msg.cmd에 확인 어떤 정신 생략) 직접 적절한 핸들러를 실행하기 위해 다음과 같이 뭔가를 할 수 : 최근

(*cmd_functions[msg.cmd])(msg) 

을, 내가 가진 유사한 "컨트롤"기능을 구현하는 C++ 코드로 작업하기 시작했지만 스위치 케이스를 사용하여 그렇게했습니다. C++에서이를 수행하기위한 표준 방법론이 있습니까? 아마도 함수 포인터 배열 인스턴스 변수가 생성자에서 초기화 되었습니까?

클래스의 V- 테이블의 런타임 사용으로 인해 솔루션이 좀 더 복잡해질 수 있다고 우려했습니다.

+0

C 메소드가 C++에서 여전히 작동하지 않습니까? – JeremyP

+0

저는 현대 C++에 대한 전문가가 아니지만, 지금부터는 [lambdas] (http://en.cppreference.com/w/cpp/language/lambda)가 있습니다. 배열이나 벡터 등을 만들 수 없습니까? 람다? – JeremyP

+0

궁금해서 왜 스위치 케이스가 붙어 있습니까? 왜 뛰어 내리는 테이블이 효과가 없을까요? – mnistic

답변

1

기본 솔루션은 실제로 v 테이블이됩니다. 각 메시지에 대해 가상 메소드가있는 기본 클래스/인터페이스를 선언하십시오.

각각의 함수를 호출하려면 switch(msg.cmd) - 명령문이 필요하지만 기본적으로 함수 테이블 초기화를 대체합니다.

더 깨끗한 취급을 원한다면 switch 문은 매개 변수 변환을 할 수도 있습니다 (따라서 메시지 핸들러는 "의미있는"인수를 얻습니다).

테이블의 "구성 가능성"을 잃어 버릴 수 있습니다. 즉, 관련없는 서로 다른 구체적인 개체에 동일한 처리기 기능을 "할당"합니다.


또 다른,보다 일반적인 옵션은 std::function<void(MyMsg const &)>와 함수 포인터의 요소를 대체 할 것 - 이것은 단지 글로벌/정적 기능을 할당하지 수 있지만 것 또한 다른 클래스의 멤버 함수, 람다 등이있다. 서명이 일치하지 않는 기존 함수로 쉽게 전달할 수 있습니다.

여기에서의 단점은 테이블을 초기화하는 데 더 많은 비용이 들며, std :: 함수를 생성하는 것은 적어도 일반적인 경우에 할당을 포함 할 것입니다. 또한 일반적인 v 테이블 별 최적화를 놓치지 않으므로 당분간 호출 당 비용이 더 높을 것으로 예상됩니다. 이 시점에서


, 당신은 또한 다른 구조를 고려하는 것이 좋습니다 : 각 메시지에 여러 "리스너"존재하는 경우에 적어도, 당신은 이벤트 가입 또는 신호를 고려하는 것이 좋습니다/슬롯 디자인 .


물론 당신은 C에서했던 방식대로 할 수 있습니다. 괜찮습니다.