наследование бриллиантов - Передача объекта класса листа в качестве параметра вместо корневого класса

0

У меня есть программа со следующей структурой наследования

                       List
                   /         \
          DoublyLinkedList   CircularlyLinkedList
                   \          /
                CircularlyDoublyLinkedList


В классе List (полностью абстрактном) у меня есть чистая виртуальная функция

     int virtual insert(List **head, int position) = 0;

который я переопределил в DoublyLinkedList и CircularlyLinkedList.
Чтобы разрешить двусмысленность в классе CircularlyDoublyLinkedList, я явно указываю, какую версию функции insert() наследует, используя оператор разрешения области :: DoublyLinkedList::insert(..)

Моя проблема заключается в том, что это утверждение

    List *cdll_head = new CircularlyDoublyLinkedList();

выдает ошибку

    "cannot convert CircularlyDoublyLinkedList* to  List*"

когда я изменяю утверждение как

    CircularlyDoublyLinkedList *cdll_head = new CircularlyDoublyLinkedList();

Я получаю еще одну ошибку, так как insert(...) принимает параметр типа List**

Как решить эту проблему без трансляции?

Теги:
inheritance
diamond-problem

1 ответ

1
Лучший ответ

При использовании множественного наследования с ромбовидными структурами вы должны использовать виртуальное наследование.

Я предполагаю, что ваш код выглядит примерно так:

class List {
...
};

class DoublyLinkedList: public List {
...
};

class CircularlyLinkedList: public List {
...
};

class CircularlyDoublyLinkedList: public DoublyLinkedList, public CircularlyLinkedList {
...
};

void doStuff() {
    List* aList = new CircularlyDoublyLinkedList();
    ...
}

который вызывает следующую ошибку:

ambiguous conversion from derived class 'CircularlyDoublyLinkedList' to base class 'List':
    class CircularlyDoublyLinkedList -> class DoublyLinkedList -> class List
    class CircularlyDoublyLinkedList -> class CircularlyLinkedList -> class List

Если вы измените наследование DoublyLinkedList и CircularlyLinkedList на виртуальную публикацию, как показано ниже:

class DoublyLinkedList: virtual public List {
...
};

class CircularlyLinkedList: virtual public List {
...
};

class CircularlyDoublyLinkedList: public DoublyLinkedList, public CircularlyLinkedList {
...
};

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

  • 0
    Большое спасибо за ответ пациента. Мой базовый класс списка полностью абстрактен со всеми функциями как чисто виртуальные. Я сделал что-то вроде DoublyLinked :: insert () в функции вставки CircularlyDoubly, так нужно ли виртуальное наследование?

Ещё вопросы

Сообщество Overcoder
Наверх
Меню