1

다음과 같은 문제가 발생했습니다. 두 패키지 A와 B가 각각 잘 작동합니다. 각각은 자체 인터페이스와 자체 구현을 가지고 있습니다. 이제는 A의 어댑터와 B의 구체적인 Implemenation을 결합한 패키지 C를 만들었습니다. C는 실제로 A의 인터페이스 만 구현하며 현재 B의 인터페이스를 상속하고 사용합니다. 대부분의 시간은 컨테이너에서 인터페이스 A에만 액세스 할 수 있었지만 이제는 액세스 할 수있는 B의 메소드도 필요합니다. 두 인터페이스는 하나의 컨테이너에서 액세스 할 수 있도록 A와 B의 모든 구현 세부 사항은 아직다면두 개의 인터페이스, 다중 상속 하나의 컨테이너에 결합?

//----Package A---- 
class IA 
{virtual void foo() = 0;}; 
// I cant add simply bar() here, it would make totally no sense here... 

class A : public IA 
{virtual void foo() {doBasicWork();} }; 

//----Package B---- 
class IB 
{virtual void bar() = 0;}; 

class B1 : public IB 
{ 
    //Some special implementation 
    virtual void bar() {} 
}; 

class B2 : public IB 
{ 
    //Some special implementation 
    virtual void bar() {} 
}; 
// + several additional B classes , with each a different implementation of bar() 

//---- Mixed Classes 
class AB1 : public B1, public A 
{ 
void foo() {A::foo(); B1::bar();} 
}; 

class AB2 : public B2, public A 
{ 
void foo() {A::foo(); B2::bar();} 
}; 

// One Container to rule them all: 
std::vector<IA*> aVec; 
AB1 obj1; 
AB2 obj2; 

int main(){ 
    iAvector.push_back(&obj1); 
    iAvector.push_back(&obj2); 
    for (std::vector<IA>::iterator it = aVec.begin(); it != aVec.end(); it++) 
    { 
     it->for(); // That one is okay, works fine so far, but i want also : 
//  it->bar(); // This one is not accessible because the interface IA 
          // doesnt know it. 
    } 
    return 0; 
} 

/* I thought about this solution: to inherit from IAB instead of A for the mixed 
    classes, but it doesnt compile, 
stating "the following virtual functions are pure within AB1: virtual void IB::bar()" 
which is inherited through B1 though, and i cant figure out where to add the virtual 
inheritence. Example: 

class IAB : public A, public IB 
{ 
// virtual void foo() = 0; // I actually dont need them to be declared here again, 
// virtual void bar() = 0; // do i? 

}; 

class AB1 : public B1, public IAB 
{ 
    void foo() {A::foo(); B1::bar();} 
}; 
*/ 

질문은, 어떻게, 패키지 A와 B 둘의 조합을 달성하기 위해 다음은 간단한 예제이다 상속받은? ,

class IAB : public virtual IA, public virtual IB 
{ 
}; 

당신의 AB1AB2가 (자신의 현재 유도에 추가) 그것에서 파생 있고, 벡터에 IAB*을 유지 :

답변

1

확실한 솔루션은 통합 인터페이스를 만드는 것입니다.

즉, B1B2은 사실상 에서 파생되어야합니다. 지시 사항이 진행되는 것처럼 보이면 A은 이어야하며 사실상 IA에서 파생됩니다.

인터페이스의 상속이 항상 가상이어야한다는 강력한 주장이 있습니다. 클래스가 에서 파생되도록 설계된 경우 에 기지가 있고 그베이스가 인 경우 가상이어야합니다 (물론 클래스가 에서 파생되지 않도록 설계된 경우 틀림없이 파생되지 않아야합니다. 그것에서). 귀하의 경우 클래식 믹싱 기술을 사용하고 있으며 일반적으로 믹스의 모든 상속은 가상입니다.

+0

예, 감사합니다. 나는 벌써 혼자 길을 이미 알아 냈다. 그러나 당신의 길은 더욱 우아 해 보입니다. 당신이 지적한이 논점에 대한 더 좋은 문서가 있습니까? –

+0

Btw. 가능한 성능 문제 옆에 가상 상속을 사용하는 단점이 있습니까? 왜냐하면, 나의 Base B-Classes는 모두 인스턴스화 된 것입니다! –

+0

@ PhilMichalski 유감스럽게도 필자는 가상 상속을 언제 사용해야하는지에 대한 많은 문서를 보지 못했습니다. 단, 필요할 때를위한 탐색은 전체 계층 구조를 아는 것에 달려 있습니다. 문제는 파생 된 클래스가 무엇을 원할지 모르는 경우입니다. 그런 경우에,'가상'는 보통 가장 안전한 내기이다. –