c++ - 菱形继承 - 传递叶类对象作为参数代替根类

标签 c++ inheritance diamond-problem

我有一个具有以下继承结构的程序

                       List
                   /         \
          DoublyLinkedList   CircularlyLinkedList
                   \          /
                CircularlyDoublyLinkedList


List 类(完全抽象)中,我有一个纯虚函数

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

我在 DoublyLinkedListCircularlyLinkedList 类中覆盖了它。
为了解决 CircularlyDoublyLinkedList 类中的歧义,我使用范围解析运算符 :: 明确指定要继承哪个版本的 insert() 函数>,例如:DoublyLinkedList::insert(..)

我的问题是这个语句

    List *cdll_head = new CircularlyDoublyLinkedList();

抛出一个错误

    "cannot convert CircularlyDoublyLinkedList* to  List*"

当我将语句更改为

    CircularlyDoublyLinkedList *cdll_head = new CircularlyDoublyLinkedList();

我收到另一个错误,因为 insert(...) 接受类型为 List** 的参数

如何在没有转换的情况下解决这个问题?

最佳答案

当使用菱形结构的多重继承时,你应该使用虚拟继承。

我假设你的代码看起来有点像这样:

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 的继承改为 virtual public 如下:

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

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

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

一切都应该正确编译。但是,有一个 additional performance cost .我建议使用一个完全抽象的列表接口(interface),该接口(interface)将由您的所有列表类继承,并进行组合以允许实现重用。

关于c++ - 菱形继承 - 传递叶类对象作为参数代替根类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19330631/

相关文章:

c++ - 给定一个类(class)成员,我如何访问同一类(class)的其他成员?

api - 在 swagger 2.0 (openapi) 中,如何在 POST 和 PUT 请求之间有不同的资源定义?

c++ - 通过 QObject 子类实现多重继承的最接近解决方案

c++ - 虚拟继承如何解决 "diamond"(多重继承)的歧义?

c++ - 我如何声明我的类的实例?

c++ - 相等字符串(数组的字符串和字符串)-c++

c++ - g++在头文件中包含目录

javascript - Waterline ORM 中的继承

Clojure - 在 map 上使用记录有什么好处

c# - 如何使用像素捕捉绘制 GlyphRun?