2013-02-26 2 views
2

Old : CRTP 기본 클래스를 통해 가상 함수를 재정의하려면 어떻게해야합니까? CRTP 기본 클래스를 통한 가상 함수 재정의

struct I { virtual void foo() = 0; }; 

template<class D> 
struct B { void foo() { } }; // provides implementation of foo in D 

struct D : I, B<D> { }; // D has an implementation of foo that should override I 

int main() { D d; } 

Error: unimplemented pure virtual method 'foo' in 'D'

간단한

: 어떻게 파생 유형을 재 구현하지 않고 가상 함수를 재정의 할 수 있습니까? (나는이 질문이 가상 함수의 정의에 어긋난다 고 생각한다).

struct I { virtual void foo() = 0; }; 

struct B { void foo() { } }; 

struct D : B, I { }; 

int main() { D d; } 
+1

수'B' 상속을 '나'? – aschepler

+0

아니요. 'B'는 'I'가 아닙니다. 'B'는'I' 인터페이스의 일부를 구현할 수 있지만 전부는 아닙니다. – gnzlbg

+0

뭔가가 I에서 상속 받아 foo를 구현해야합니다. 한 가지 가능성은 D가이를 수행하여 B로 전달하는 것입니다. 또는 B에 다른 템플리트 매개 변수를 추가하고 거기에서 B를 상속받을 수 있습니다. 셀 수없는 가능성이 있습니다. 단 하나만 있으면됩니다. 무엇인가는 I로부터 상속 받아 구현해야합니다. – PlasmaHH

답변

1

당신이 불필요하게 두 개의 서로 다른 개념을 혼합하고 있습니다 : CRTP, 그리고

CRTP 컴파일 시간 polyrmorphism에 사용되는 가상 함수의 구현을 상속, 런타임 다형성 말했다

에 대한 가상 함수, 가상 상속 계층에서 dominance의 가상 함수 구현으로 상속받을 수 있습니다.이 상속 계층은 java/C# 구현 상속의 효과를 대략적으로 나타냅니다.


예 : 사소한 래퍼 B<D>::foo() 전화로

struct tutti_i 
{ 
    virtual int frutti() const = 0; 
}; 

struct tutti_impl_1 
    : virtual tutti_i 
{ 
    int frutti() const override { return 42; } 
}; 

struct base 
    : virtual tutti_i 
{}; 

struct derived 
    : base 
    , tutti_impl_1 
{}; 

#include <iostream> 
int main() 
{ 
    tutti_i&& tutti = derived(); 
    std::cout << tutti.frutti() << std::endl; 
} 
+0

사실, 질문의 간단한 부분에서 CRTP를 제거했습니다. 나는 내가 뭘하려고했는지 더 잘 보여줄 것으로 생각한다. – gnzlbg

+0

Downvoter, 다른 사람을 오도하는 대신 도움이 될 수 있도록 downvoting에 대한 이유를 설명하십시오. –

+0

흠, 처음에는 질문자가 CRTP를 사용하려는 것 같았 기 때문에 처음에는 답이 원래 질문에 응답하지 않은 것 같았습니다.나는 downvoting하기 전에 질문에 대한 의견을 읽었어야했다. 죄송하지만 지금은 잠겨 있습니다. –

1

당신은 D::foo()을 구현할 수 있습니다. 당신은 인터페이스 "는 foo를 구현"분리 수, 명백한하지만 어설픈 void foo() { B::foo(); } 솔루션 게다가

#define WRAP(CLASS, METHOD) \ 
    METHOD() { return CLASS::METHOD(); } 

struct D : I, B<D> 
{ 
    void WRAP(B<D>, foo); 
}; 
2

:이 작업을 수행 할 필요가 많은 장소가있는 경우처럼 도와 매크로를 만들 수 더 완전한 인터페이스 I에서 : 사람들을 위해

struct FooInterface { 
    virtual ~FooInterface() {} 
    virtual void foo() = 0; 
}; 

struct I : public virtual FooInterface {}; 

template<class D> 
struct B : public virtual FooInterface { void foo() { } }; 

struct D : I, B<D> {}; 

int main() { D d; } 
0

B는 I에서 상속 여부를 상관 없어, 당신은 또한 CRTP과이를 구현 할 수있는 원래 질문 :

struct I { virtual void foo() = 0; }; 

template <class D> 
struct B : I { void foo(){ /* Do something fancy with D's type */ } }; 

struct D : B<D> { }; 

그리고 foo에의 이행이 항상 가장 파생 형이되도록이 더 상속을 필요로하는 경우, 당신은 foo는의 구현이 사용됩니다 어떤 명확하게하기 위해 중간 형식을 도입 할 수 있습니다 :

struct I { virtual void foo() = 0; }; 

template <class T> 
struct B : virtual I { void foo() { /* Do something fancy with the most-derived type */ }}; 

struct D : B<D> { }; 

template <typename Base, typename Derived> 
struct InheritFrom : public Base, public B<D> { void foo() { B<D>::foo(); } }; 

struct FurtherDerived : InheritFrom<D, FurtherDerived> { }; 
관련 문제