2009-06-18 3 views
2

Я ищу чистый способ сделать это с давних времен. В моей проблеме есть 3 класса, которые не разделяют общего родителя, но каждый из них имеет несколько методов с тем же именем (A.doSomething, B.doSomething, C.doSomething). Следовательно, имея такую ​​же сигнатуру функции, класс D, наследующий от A и использующий метод doSomething(), будет «выглядеть одинаково» на E, наследующем от B или C.Множественная иерархия наследования

Вот набросок того, что я хотел бы быть в состоянии сделать:

class Base { 
    public: 
    void myMethod(void) { doSomething(); } 
}; 

class Independent { 
    public: 
     doSomething(); 
}; 

clase Derived : public Base : public Independent { 
(...) 
}; 

int main(void) { 
    Derived *derivedObject = new Derived(); 
    derivedObject->myMethod(); 
} 

В этой задаче, объект типа «Индепендент» обеспечивается библиотекой, что я не могу изменить. Я хотел бы определить базовый класс, который использует методы, которые позже будут унаследованы. Я не мог найти правильный способ сделать это с помощью виртуального наследования, не вызывая неоднозначной компиляции.

+0

Не могли бы вы объяснить вашу проблему немного более четко? Я вижу только один метод, называемый «doSomething» в этом фрагменте кода, но вы указываете три класса, которые есть в описании, и вы не комментируете, для чего должен использоваться метод myMethod. –

ответ

5

У вас здесь неприятная ситуация. Одним из решений этой проблемы было бы с помощью Любопытно Повторяющееся шаблона Шаблон для выполнения наследования во время компиляции, например:

template <typename D> 
class Base { 
    public: 
     void myMethod(void) { static_cast<D*>(this)->doSomething(); } 
}; 

class Independent { 
    public: 
     void doSomething(); 
}; 

clase Derived : public Base : public Independent { 
    /*...*/ 
}; 

int main(void) { 
    Derived *derivedObject = new Derived(); 
    derivedObject->myMethod(); 
} 

В качестве альтернативы, вы можете выбрать, чтобы поставить класс посредническая между направить Independent (я предполагаю, у вас есть много классов, основанных на тех же Base и Independent, и просто не нужно делать это для каждого класса).

template <typename D> 
class Base { 
    private: 
     virtual void doSomethingImpl(); 
    public: 
     void myMethod(void) { doSomethingImpl(); } 
}; 

class Independent { 
    public: 
     void doSomething(); 
}; 

class IndependentWrapper : public Base : public Independent { 
    private: 
     void doSomethingImpl() { Independent::doSomething(); } 
}; 

clase Derived : public IndependentWrapper { 
    /*...*/ 
}; 

int main(void) { 
    Derived *derivedObject = new Derived(); 
    derivedObject->myMethod(); 
} 
Смежные вопросы