당신이 multimethods 일명, multiple dispatch라고 요구하고있다. C++ 언어의 기능은 아닙니다.
특별한 경우에 대한 해결 방법이 있습니다,하지만 당신은 몇 가지 구현 자신을 일을 피할 수 없다. 여러 파견
하나 개의 일반적인 패턴은 "재발 dispatch", 일명 "재귀 이연 파견"라고합니다. 기본적으로 하나의 가상 메소드는 하나의 매개 변수 유형을 해결 한 다음 모든 매개 변수가 해결 될 때까지 다른 가상 메소드를 호출합니다. 외부의 기능 (있는 경우)은 이러한 가상 메소드 중 첫 번째를 호출합니다. N이 유도 된 클래스를 가정
,이 최초의 파라미터를 해결하는 하나 개의 방법이 될 것이다 N 등등 제 등을 해결하기 위해 상기 제 N 개의 * n을 해결하기 위해 - 최악 어쨌든. 이는 상당한 수작업으로, typeid를 기반으로하는 조건부 블록을 사용하는 것이 처음 개발하는 경우 더 쉬울 수도 있지만 재 구현을 사용하는 유지 관리가 더 강력합니다.
class Base;
class Derived1;
class Derived2;
class Base
{
public:
virtual void Handle (Base* p2);
virtual void Handle (Derived1* p1);
virtual void Handle (Derived2* p1);
};
class Derived1 : public Base
{
public:
void Handle (Base* p2);
void Handle (Derived1* p1);
void Handle (Derived2* p1);
};
void Derived1::Handle (Base* p2)
{
p2->Handle (this);
}
void Derived1::Handle (Derived1* p1)
{
// p1 is Derived1*, this (p2) is Derived1*
}
void Derived1::Handle (Derived2* p1)
{
// p1 is Derived2*, this (p2) is Derived1*
}
// etc
어려울 것 파생 클래스에 대한 템플릿을 사용하여이 구현하고, 아마, 읽을 이상 유지할 매우 깨지기 쉬운 것 처리 할 수있는 템플릿 메타 프로그래밍. 비 템플릿 메소드를 사용하여 디스패치를 구현 한 다음 추가 기능으로 확장하는 mixin 템플릿 (기본 클래스를 템플릿 매개 변수로 사용하는 템플릿 클래스)을 사용하면 그리 나쁘지는 않을 수 있습니다.
visitor design pattern
밀접 (기본적하여 구현)를 재 전달할 IIRC에 관한 것이다. ++
다른 방법은 문제를 처리 할 수 있도록 설계 언어를 사용하는 것입니다, 그리고 C와 함께 잘 작동 몇 가지 옵션이 있습니다. 하나는 treecc - AST 노드 및 lex 및 yacc와 마찬가지로 출력으로 "소스 코드"를 생성하는 다중 발송 작업을 처리하기위한 도메인 별 언어를 사용하는 것입니다. 그냥 간단하게 동적으로 입력 된 값 클래스 ID, IYSWIM을 할 수 있습니다 -
는 파견 결정을 처리하기 위해 수행 모든
는 AST 노드 ID를 기반으로 스위치 문을 생성합니다. 그러나 이것들은 당신이 쓰거나 유지할 필요가없는 switch 문이다. 이것은 중요한 차이점이다. 내가 가지고있는 가장 큰 문제는 AST 노드가 자신의 소멸자 처리를 조작했다는 것입니다. 즉, 특별한 노력을하지 않으면 멤버 데이터에 대한 소멸자가 호출되지 않습니다. 즉, 필드의 POD 유형에 가장 적합합니다.
다른 옵션은 다중 방법을 지원하는 언어 전 처리기를 사용하는 것입니다. Stroustrup은 한 곳에서 여러 방법을 지원하기위한 아이디어가 상당히 발달했기 때문에 부분적으로 이러한 것들이 몇 가지 있습니다. CMM은 하나입니다. Doublecpp이 또 하나입니다. 또 다른 하나는 Frost Project입니다. 나는 CMM이 Stroustrup이 설명한 것에 가장 가깝다고 생각하지만, 나는 체크하지 않았다.
는 궁극적으로하지만, 여러 파견은 런타임 결정을 내릴 수있는 방법이며, 같은 결정을 처리하는 방법에는 여러 가지가 있습니다. 전문가 DSL은 상당한 양의 번거 로움을 가져 오므로 일반적으로 여러 번 발송해야하는 경우에만 수행합니다. Redispatch와 방문자 패턴은 강력한 WRT 유지 관리이지만 복잡성과 복잡함을 희생합니다. 컴파일 타임에 처리되지 않은 사건의 가능성을 탐지하는 것이 불가능하지는 않더라도 어렵다는 것을 명심하면서 간단한 조건문이 간단한 경우에 더 나은 선택 일 수 있습니다.
자주의 경우와 마찬가지로
는 ++ 적어도 C에, 그것을 아무도 올바른 방법이 없습니다.
당신은 완전한 클래스 유형을 모른다는 것을 언급해야한다고 생각합니다. 여러분은 단지'Base &'를 알고 있습니다. 내 자신을 포함 해 여러 답변이 'Derived '이라는 정확한 유형을 알고 있다고 가정했습니다. –
답변에 대한 의견에서 주목하기 : 추가 요구 사항은 함수가 템플릿이 될 수 없다는 것입니다. 해당 Base * (Base &, Base &) 서명이 있어야합니다. –
질문에 더 명확하게 제한 사항을 포함 시켰습니다. –