Использование наследования от конкретного класса для реализации чистого виртуального метода C++

Я хочу реализовать чисто виртуальные методы из интерфейса, используя реализацию, предоставляемую конкретным классом, без необходимости явного вызова метода из конкретного класса. Пример:

class InterfaceA{  
public:  
    virtual void foo() = 0;  
};

class InterfaceB:public InterfaceA{  
public:  
   virtual void bar() = 0;  
};

class ConcreteA : public InterfaceA{  
public:  
   virtual void foo(){}//implements foo() from interface  
};

class ConcreteAB: public InterfaceB, public ConcreteA{  
public:  
    virtual void bar(){}//implements bar() from interface  
};

В этом сценарии компилятор запрашивает реализацию foo() в классе ConcreteAB, потому что в InterfaceB она не реализована и унаследована от InterfaceA.

Есть способ указать компилятору использовать реализацию из ConcreteA без использования оболочки, вызывающей ConcreteA::foo()?


person Daniel Saad    schedule 26.12.2012    source источник
comment
Код выглядит нормально: liveworkspace.org/code/2W44n2$3   -  person SomeWittyUsername    schedule 26.12.2012
comment
Как только я добавлю ;, которого вам не хватает, это отлично скомпилируется на g++ 4.5. Можете ли вы показать нам реальный код, который вызывает проблему?   -  person Mark B    schedule 26.12.2012
comment
Я не хочу этого делать. Я хочу сообщить компилятору, что реализация предоставляется из ConcreteA без использования оболочки/заглушки. Есть способ?   -  person Daniel Saad    schedule 26.12.2012
comment
ideone.com/aN0Eam — у вас глючит компилятор.   -  person user93353    schedule 26.12.2012
comment
вставьте сообщение об ошибке, которое вы получаете   -  person marcinj    schedule 26.12.2012
comment
Код, который у вас есть, отлично работает. Вы должны быть более ясны в отношении проблемы, которая, по вашему мнению, у вас есть.   -  person Mark Ransom    schedule 26.12.2012
comment
Извините, я забыл унаследовать интерфейс A в интерфейсе B.   -  person Daniel Saad    schedule 26.12.2012
comment
Почему InterfaceB вообще ребенок InterfaceA? Мне кажется, это дизайнерский запах.   -  person Mark B    schedule 26.12.2012
comment
Марк, я хочу использовать полиморфное поведение с помощью InterfaceB, поэтому мне нужно наследовать от InterfaceA, чтобы использовать методы из interfaceA.   -  person Daniel Saad    schedule 26.12.2012


Ответы (2)


Сделайте InterfaceA виртуальным базовым классом.

class InterfaceB : public virtual InterfaceA {  
public:  
   virtual void bar() = 0;  
};

class ConcreteA : public virtual InterfaceA {  
public:  
   virtual void foo(){}//implements foo() from interface  
};
person user93353    schedule 26.12.2012
comment
Большое спасибо! Это ключ =D - person Daniel Saad; 26.12.2012

Вам нужно виртуальное наследование.

Интерфейс А, находящийся на вершине иерархии, должен быть унаследован практически всеми непосредственными подклассами.

class InterfaceB:public virtual InterfaceA{  
public:  
   virtual void bar() = 0;  
};

class ConcreteA : public virtual InterfaceA{  
public:  
   virtual void foo(){}//implements foo() from interface  
};
person arayq2    schedule 26.12.2012