2017-02-23 81 views
2

У меня есть следующее условие:Наследование как абстрактный базовый интерфейс и его реализации дает C2259

абстрактная базовый класс с многих чисто виртуальных функций:

interface IBase 
{ 
    virtual void foo1() = 0; 
    virtual void foo2() = 0; 
    virtual void foo3() = 0; 
    virtual void foo4() = 0; 
    virtual void foo5() = 0; 
    // ... 
    virtual void fooN() = 0; 
}; 

Два маленьких интерфейсов, которые наследуют его:
Версия -А:

interface IBaseExt_A : 
    public IBase 
{ 
    virtual void foo_A() = 0; 
}; 

Версия-Б:

interface IBaseExt_B : 
    public IBase 
{ 
    virtual void foo_B() = 0; 
}; 

создать базовый класс, который реализует все функции IBase интерфейса:

class CBase : 
    public IBase 
{ 
public: 
    virtual void foo1() { /* Do something... */} 
    virtual void foo2() { /* Do something... */} 
    virtual void foo3() { /* Do something... */} 
    virtual void foo4() { /* Do something... */} 
    virtual void foo5() { /* Do something... */} 
    // ... 
    virtual void fooN() { /* Do something... */} 
}; 

Теперь я хочу, чтобы реализовать обе версии, полученные с минимальным кодом.
Я надеялся сделать что-то вроде:

class CBaseExt_A : 
    public IBaseExt_A, 
    public CBase 
{ 
public: 
    virtual void foo_A() { /* Do something... */} 
}; 

Видимо, это дает ошибку:
C2259: 'CBaseExt_A': cannot instantiate abstract class...
Эти ошибки относятся ко всем IBase функций интерфейса.

Я знаю, что могу решить длинный путь, передав все IBase функции CBase реализации:

class CBaseExt_A : 
    public IBaseExt_A, 
    public CBase 
{ 
// IBase implementation: 
public: 
    virtual void foo1() { CBase::foo1();} 
    virtual void foo2() { CBase::foo2();} 
    virtual void foo3() { CBase::foo3();} 
    virtual void foo4() { CBase::foo4();} 
    virtual void foo5() { CBase::foo5();} 
    // ... 
    virtual void fooN() { CBase::fooN();} 

// IBaseExt_A implementation: 
public: 
    virtual void foo_A() { /* At last - do what we came here for...*} 
}; 

Но это делает мой небольшой классCBaseExt_A стать большим и сложным.
Есть ли способ избежать всего этого кодирования делегирования руководства?

Большое спасибо, Пазо

+1

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

+1

Интерфейс ключевого слова в C++? Какой компилятор вы используете? –

+0

@KirillKobelev - Я добавил: #define interface struct – PazO

ответ

1

Вы должны использовать следующий код:

interface IBase 
{ 
    virtual void foo() = 0; 
    ...... 
}; 

class CBase : virtual public IBase 
{ 
    void foo() { } 
    ...... 
}; 

interface IBaseExt_A : virtual public IBase 
{ 
    virtual void foo_A() = 0; 
}; 

struct CBaseExt_A : public IBaseExt_A, public CBase 
{ 
    virtual void foo_A() { /* Do something... */ } 
}; 

Обратите внимание, что оба места, где унаследовал IBase класса должны быть помечены как виртуальные.

+0

Спасибо! Это работает – PazO

0

Я думаю, вы должны указать один из двух наследования быть виртуальным.

То есть алмаз наследование, где

IBase это верхний уровню

IBaseExt_A и CBase является средним уровнем

CBaseExt_A İŞ нижнего уровня

так в CBaseExt_A вы хотите задать из которого путь реализует верхний уровень, я бы сказал, что вы можете указать наследование CBase в IBaseExt_A как общедоступное виртуальное, а не просто публичное.

class CBaseExt_A : 
public IBaseExt_A, 
public virtual CBase 
{ 
public: 
    virtual void foo_A() { /* Do something... */} 
}; 
+0

Я обнаружил, что мне нужно добавить «виртуальное» ключевое слово во всех местах, где «IBase» наследуется ... – PazO

Смежные вопросы