如何在一个链表中存储不同类型的节点?

时间:2017-12-04 18:33:19

标签: c++ linked-list

我试图在一个链表中存储不同类型的节点,我构建了一个结构

struct node{struct node *next};

和两个班级,

第一堂课是

class doc1
{
 private : int data ;
}

第二堂课是

class doc2
{
 private : double number ;
}

和一个包含整个列表的类

class list : public doc1 ,public doc2
{
public : void add_node();
private : struct node * head = NULL ;
}

其实我在问这个" head"指针指向不同的节点 - 每个节点可能包含来自两个不同类的对象 - 。

模板很好解决这个问题吗?!

谢谢。

1 个答案:

答案 0 :(得分:2)

  

和一个包含整个列表的类

class list : public doc1 ,public doc2
{
public : void add_node();
private : struct node * head = NULL ;
}

对不起,我需要这样说,但这没有任何意义。

继承不是正确的工具aggregate

您的列表包含 doc1doc2个实例,但不是 doc1doc2,但拥有这些或收集弱引用

最灵活的方法是为doc类型提供一个公共(抽象)基类,并在node类中为它们存储std::unique_ptr

class doc {
protected:   // make doc abstract, it can only be used with directly inheriting
    doc() {} // classes
public:
    virtual ~doc() {} // make doc polymorphic
};

class doc1 : public doc {
    // special stuff
};

class doc2 : public doc {
    // special stuff
};

struct node { 
    node *next;
    std::unique_ptr<doc> doc_data;
};
class list {
public: 
    list() : head(nullptr) {}
    template<tyoename T>
    void add_node(const T& data) {
         static_assert("data must derive from doc",std::is_base_of<doc,T>::value);
         node* newNode = new node(); // Note you still need to do the memory 
                                     // management for your node instances!
         newNode->doc_data = std::make_unique<T>(data); // T needs to be 
                                                        // copy constructible
         // linked list management code ...
    }
private: 
    node* head;
}
  

模板很好解决这个问题吗?!

正如您在上面的示例中所看到的,我使用了模板add_node()函数来方便地使用doc1doc2类型。

模板还可以帮助您使整个list类适用于任意数据类型:

template<typename T>
class MyList {
public:
    // I'm using a nested node type here
    struct node {
        node* next;
        T data;
        node() : next(nullptr), data() {}
        node(const T& value): next(nullptr), data(value) {}
    };

    MyList() : head(nullptr) {}
    void add_node(const T& value) {
        node* new_node = new node(value);
        // linked list management code ...
    }
private:
    node* head;
};

对于上述实现,您还可以利用std::unique_ptr包含doc个实例并混合使用类型:

MyList<std::unique_ptr<doc>> myList;

这当然也适用于不相关的类型,如:

MyList<doc1> myDoc1List;
MyList<doc2> myDoc2List;
MyList<int> myInt1List;
MyList<double> myDouble1List;

最简单的方法当然是使用c++ standard containers library已有的链表实现:

std::list<std::unique_ptr<doc>> myLinkedDocList;