使用模板的C ++链接列表

时间:2013-08-06 01:46:58

标签: c++ templates

我有以下课程:

typedef struct Listable
{
    struct Listable *next;
    struct Listable *prev;

    // Lots of other class members not pertaining to the question excluded here
} Listable;

我继承了它:

typedef struct Object : Listable
{
} Object;

问题是,当我做这样的事情时:

Object *node;
for (node = objectHead; node; node = node->next);

我收到'node = node-> next'的错误,因为node-> next属于Listable类型,而node属于Object类型。

如何在Listable基类中使用模板来生成prev&下一个指针将其类型更改为正在使用的类?

也许是这样的:

typedef struct Listable<T>
{
    struct Listable<T> *next;
    struct Listable<T> *prev;

    // Lots of other class members not pertaining to the question excluded here
} Listable;

我继承了它:

typedef struct Object : Listable<Object>
{
} Object;

我有超过10年的C,但对模板等C ++功能来说还是比较新的。所以我不确定我应该使用什么语法。

3 个答案:

答案 0 :(得分:3)

模板语法本身非常简单:

template <typename T>
struct Listable
{
    T *next;
    T *prev;

    // Lots of other class members not pertaining to the question excluded here
};

所以,当它被Object继承时,就像这样:

struct Object : Listable<Object>
{
};

Object将获得nextprev指针。

由于Listable正在管理指针,因此您需要注意Rule of Three。也就是说,您必须考虑在销毁,复制构造和分配期间需要执行的操作,以便正确管理内存。

答案 1 :(得分:1)

你确定不想只使用:

Listable *node;
for (node = objectHead; node; node = node->next);

代替?即使node实际上是一个Object,这也会起作用,因为Object继承自Listable。

此外,正如Jerry所提到的,已经有一个内置的templated, doubly linked list是C ++标准模板库的一部分。您也不需要手动编写for循环,因为您也可以使用std::foreach to operate on it

#include <list>
#include <algorithm>
#include <iostream>

struct Sum {
    Sum() { sum = 0; }
    void operator()(int n) { sum += n; }

    int sum;
};

int main()
{
    std::list<int> nums{3, 4, 2, 9, 15, 267};

    Sum s = std::for_each(nums.begin(), nums.end(), Sum());

    std::cout << "sum: " << s.sum << '\n';
    std::cout << "elements:  ";

    //Or, you could use iterate over each node in the list like this
    for (auto n : nums) {
        std::cout << n << " ";
    }
    std::cout << '\n';
}

答案 2 :(得分:0)

您似乎将链接列表的概念与链接列表中的节点的概念混为一谈。然后你添加一个Object(假设)是这些混淆的节点/链接列表之一。至少在我看来,这听起来很混乱和困惑。

我更愿意看到类似的内容:

template <class T>
class linked_list { 
    class node {
        T data;
        node *next;
    public:
        node(T data, node *next = NULL) : data(data), next(next) {}    
    };

    node *head;
public:
    void push_back(T const &item);
    void push_font(T const &item);
    // etc.
};

警告:当然,对于真正的代码,你可能根本不想使用链表,2)即使你这样做,也应该是std::list