我有以下课程:
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 ++功能来说还是比较新的。所以我不确定我应该使用什么语法。
答案 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
将获得next
和prev
指针。
由于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
。