Наследование как абстрактного класса, так и реализации класса в C ++ - PullRequest
1 голос
/ 03 марта 2010

Надеюсь, это простой вопрос.

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

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 {
}

Ответы [ 4 ]

2 голосов
/ 03 марта 2010

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

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

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

class C : public B {
}

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

1 голос
/ 03 марта 2010

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

class C : public A, public B {
void func1(){ B::func1(); }
}
1 голос
/ 03 марта 2010

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

0 голосов
/ 03 марта 2010

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

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

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

Кто-то выше опубликовал что-то вроде:

class C : public A, public B 
{
      // implement A::func1()
      virtual void func1()
      { 
           // delegate to inherited func1() in class B
           B::func1(); 
      }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...