2012-08-27 5 views
0

내 질문은 다음과 같은 구조에 관련이 있습니다 enter image description here더블 상속 :

추상 수준이 "진짜"클래스 (D1과 D2)의 멤버 함수를 제공하기 위해 바로 여기에 있습니다. 고도로 최적화되어야 할 필요가 있기 때문에 추상적 인 레벨의 소멸자가 보호됩니다. B0-C1-C2-D1을 가진 부분은 다음과 같은 경우에 완벽하게 확인된다

  1. B0, C1 및 C2는 회원이 다른 이름으로

    를 작동했다?

  2. C1과 C2는 같은 이름의 기능을 가지고 있습니다 (예 : myFunction)?

  3. C1 및 C2와 D1은 같은 이름의 기능을 가지고 있습니다 (예 : myFunction)?

  4. B0와 C2는 같은 이름이지만 C1이 아닌 함수를 가지고 있습니다 (예 : myFunction)?

각 경우에 어떤 버전의 함수가 D1에 의해 호출됩니까?

편집 :

template<class CRTP> class A0 
{ 
    public: 
     void myfunction1(); 
    protected: 
     ~A0(); 
     double mymember; 
}; 

template<class CRTP> class B0 : public A0<CRTP> 
{ 
    public: 
     void myfunction2(); 
    protected: 
     ~B0(); 
}; 

template<class CRTP> class C1 : public B0<CRTP> 
{ 
    public: 
     void myfunction3(); 
    protected: 
     ~C1(); 
}; 

template<class CRTP> class C2 : public B0<CRTP> 
{ 
    public: 
     void myfunction4(); 
    protected: 
     ~C2(); 
}; 

class D1 : public C1<D1>, public C2<D1> 
{ 
    public: 
     void myfunction5(); 
}; 
+2

사진에 'D0'이 (가) 없습니다. * 다른 사람들이 그런 디자인에 혼란 스러울 것이 분명하지만 혼란스러워하는 것처럼 보입니다! :-) –

+0

감사합니다. 편집 : D0 및 D1 -> D1 및 D2 – Vincent

+0

그림은 좋지만 코드만큼 유용하지는 않습니다. 특히,'C' 레벨까지는 CRTP가있는 템플릿 만있는 것 같습니다. 맞습니까? –

답변

0

난 당신이 클래스에 두 번 A0B0을 갖는 확인하지 않는 한 서로 다른 클래스 (B0<C1>B0<C2>)이 있지만 그것은, 괜찮아요 언급하지 않았다. 일부 전문화 과정을 거치지 않는 한 가장 가능성이 높은 것은 not what you want입니다.

이에 대한 가능한 해결책은 다중 상속을 제거 something like this를 다음과 같습니다

template<class CRTP, class Base = B0<CRTP> > class C1 : public Base 
{ 
    public: 
     void myfunction3(); 
    protected: 
     ~C1(); 
}; 

template<class CRTP, class Base = B0<CRTP> > class C2 : public Base 
{ 
    public: 
     void myfunction4(); 
    protected: 
     ~C2(); 
}; 

class D1 : public C2<D1,C1<D1>> 
{ 
    public: 
     void myfunction5(); 
}; 

그래서, 당신은 거기에 그 다이아몬드를 할 경우, 여러 개의 기본 클래스 인스턴스없이 무엇을 할 수 있는지?
아니요, 왜냐하면
)는 기본 클래스가 다르므로
b)는 C++ 가상 상속에서는 vtable 클래스에서만 작동합니다.

0

다소 주관적 "완벽하게 확인"이지만, 상황의 모든 언어에서 잘 정의 : 코드의 빠른 조각은을 설명합니다.

diamond inheritance과 관련된 문제는 D1에서 발생할 수 있습니다. 의 경우 virtual inheritance을 사용하여 C1C2을 공통 기반에서 상속받을 수 있습니다. 우리가 추측하기에는 항상 적절하지 않습니다.

1)

그들은 다른 방법, 충돌없이 서로 다른 클래스입니다. 문제가있는 것 D1하지만

2)

C1 또는 C2 내에서 아무런 문제가 없습니다.

3)

당신은 D1에서 그것을 정의하는이 수 있습니다. 상속 된 myFunction 호출은 외부에서 숨겨집니다 (액세스 할 수 없음). 당신과 같이 D1 내에서 호출 할 수 있습니다 CRTP와

struct D1 { 
    void myFunction() { 
    C1::myFunction(); 
    C2::myFunction(); 
    } 
} 

이가 할 성가신 될 것입니다. 당신의 온건함을 유지하기 위해 클래스 정의에서 typedef를 사용하는 것이 좋습니다.

C1

4) B0가 제공하는 어떤 기능을해야합니다. 액세스 할 수없는 경우 참조하면 컴파일러 오류가 발생합니다.

솔직히이 디자인에 대해 권하고 싶습니다. 모든 것을 작은 콘크리트로 분해하고 합성하십시오. 이것을 유지하는 것은 프로젝트가 아니라 커리어가 될 것입니다.