2010-03-03 1 views
0

Надеюсь, это простой вопрос.Наследование как абстрактного класса, так и класса в C++

Могу ли я наследовать как абстрактный класс, так и его реализацию? То есть можно ли заставить работать?

class A { 
    virtual void func1() = 0; 
} 

class B { 
    void func1() { /* implementation here */ } 
} 

class C : public A, public B { 
} 

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


Я решил это путем создания «композитный класс» под названием D, который наследует от A & B, но содержит код реализации ранее содержащийся в B. Это делает моя модель наследования менее чистый, но он решает эту проблему без требуя дублирования кода. И, как я заметил в комментариях ниже, это делает мои соглашения об именах довольно грубыми.

class A { 
    virtual void func1() = 0; 
} 

class B { 
    // Other stuff 
} 

class D : public A, public B { 
    void func1() { /* implementation here */ } 
} 

class C : public D { 
} 

ответ

0

Как указал Кирилл: Ваша предпосылка неверна.

Класс B в вашем примере не наследует класс A (его нужно объявить первым).

Таким образом, B.func1() является чем-то совершенно отличным от A.func1() для компилятора. В классе С он ждет вас, чтобы обеспечить реализацию A.func1()

Кто-то выше разместил что-то вдоль линий:

class C : public A, public B 
{ 
     // implement A::func1() 
     virtual void func1() 
     { 
      // delegate to inherited func1() in class B 
      B::func1(); 
     } 
} 
+0

Ну, я думаю, мы сузили проблему к нахождению хорошего именования: класса LuaPolygonalGameObject: общественному GameObject, общественному Polygon, общественному LuaItem // Композитного класса Тьфу! Но он скомпилируется! – Watusimoto

1

Make B наследует от A. Если это не представляется возможным, используя виртуальное наследование также может работать (я не совсем уверен в этом).

+1

В этом случае А и В очень разные классы, и на самом деле не имеют ничего общего, кроме небольшого числа функций. – Watusimoto

+0

Когда вы используете не виртуальное наследование, C получает две полностью отдельные функции func1. – Tronic

+0

было бы неплохо взломать, если бы B не наследовал от A, и вы пытались заставить его переопределить функцию A путем их сглаживания в C также наследование диаманта все равно потребует, чтобы B наследовал от A, он должен был бы be: класс B: виртуальный A класс C: виртуальный A, B – matt

1

Если вы хотите повторно использовать код из класса B в классе C, попробуйте сделать что-то вроде этого:

class C : public A, public B { 
void func1(){ B::func1(); } 
} 
2

class B не является реализация class A в вашем коде. Class B должен быть унаследован от class A и func1 должен быть виртуальным. Только в этом случае class B будет реализовывать class A. И тогда нет никакой необходимости наследовать от А и В.

class A { 
    virtual void func1() = 0; 
} 

class B : public A { 
    virtual void func1() { /* implementation is here */ } 
} 

class C : public B { 
} 

В противном случае вы получите нереализованную чистую виртуальную функцию func1.

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

  • Нет связанных вопросов^_^