3

我有以下课程:

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 和 next 指针将其类型更改为正在使用的类?

也许是这样的:

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++ 功能相当陌生。所以我不确定我应该使用什么语法。

4

3 回答 3

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将得到nextandprev指针。

由于Listable是管理指针,因此您需要注意三法则。也就是说,您必须考虑在销毁、复制构造和分配过程中需要做什么,以便正确管理内存。

于 2013-08-06T01:54:37.013 回答
1

你确定你宁愿不只是使用:

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

反而?即使节点实际上是一个对象,这也会起作用,因为对象继承自 Listable。

此外,正如 Jerry 所提到的,已经有一个内置的模板化双向链表,它是 C++ 标准模板库的一部分。您也不需要手动编写 for 循环,因为您还可以使用std::foreach 对其进行操作

#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';
}
于 2013-08-06T02:33:32.727 回答
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.
};

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

于 2013-08-06T02:25:53.493 回答