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

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

                       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**

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

0

Решение

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

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

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

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

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector