два интерфейса, множественное наследование объединить в один контейнер?

Я наткнулся на следующую проблему: у меня есть два пакета A и B, работающие нормально для каждого. У каждого свой интерфейс и своя реализация. Теперь я создал пакет C, объединяющий адаптер A с конкретной реализацией B. C фактически только реализует интерфейс 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, чтобы оба интерфейса были доступны из одного контейнера, а все детали реализации из A и B все еще наследуются?

2

Решение

Очевидное решение — создать комбинированный интерфейс:

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

, иметь свой AB1 а также AB2 извлечь из этого (в дополнение к их
текущие выводы), и сохранить IAB* в векторе.

Это означает, что B1 а также B2 должен также происходить практически из
IB; учитывая направление, кажется, что дела идут, A должен
вероятно, также получены практически из IA,

Есть веские аргументы, что наследование интерфейса
всегда должен быть виртуальным. Не заходя так далеко: если класс
предназначен для получения из, а также у него есть основания, те основания
должно быть виртуальным (и, возможно, если класс не предназначен для
быть производным от вас, вы не должны получать от него). В твоем случае,
вы используете классическую технику миксина, и, как правило,
самое простое решение для всего наследования в миксине, чтобы быть
виртуальная.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]