菱形 传递叶类对象作为参数来代替根类

diamond Passing leaf class object as parameter in place of root class

本文关键字:参数 叶类 对象 菱形      更新时间:2023-10-16

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

                       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 的继承更改为虚拟公共,如下所示:

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

一切都应该正确编译。但是,存在额外的性能成本。我建议使用一个完全抽象的列表接口,该接口将由所有列表类继承,并组合以允许实现重用。