在实现FIFO时,我使用了以下结构:
struct Node
{
T info_;
Node* link_;
Node(T info, Node* link=0): info_(info), link_(link)
{}
};
我认为这是许多STL容器(例如List)的众所周知的技巧。这是一个好习惯吗?当你说Node有一个带有类型指针的成员时,它对编译器意味着什么?这是一种无限循环吗?
最后,如果这是一个不好的做法,我将如何实现更好的FIFO。
编辑:人们,这完全是关于实施的。我对STL库非常熟悉,并且知道来自多个库的大量容器。我想与能够提供良好实施或良好建议的人讨论。答案 0 :(得分:2)
这是一个好习惯吗?
我没有看到任何特别错误。
当你说Node有一个带有类型指针的成员时,它对编译器意味着什么?
存储指向同一类对象的指针的类没有任何问题。
最后,如果这是一个不好的做法,我将如何实现更好的FIFO。
我会使用std::queue
;)
答案 1 :(得分:2)
显然,您使用的是link-list作为队列的底层实现。这没什么特别糟糕的。
仅供参考,就实现而言,std :: queue本身使用std :: deque作为其底层实现。 std :: deque是一个更复杂的数据结构,由巧妙管理的动态数组块组成。 它最终比链表更好,因为:
答案 2 :(得分:1)
您可以使用现有的FIFO std::queue。
答案 3 :(得分:1)
这是实现节点的一种好方法。节点指针用于创建指向容器中下一个节点的链接。你是对的,它可以用来创建一个循环。如果容器中的最后一个节点引用第一个节点,则迭代该容器将遍历所有节点。
例如,如果容器是FIFO队列,则指针将引用队列中的下一个节点。也就是说,link_
的值将是另一个类Node
的实例的地址。
如果值类型T
实现了一个昂贵的复制构造函数,那么更高效的Node
类将是
struct Node
{
T * info_;
Node* link_;
Node(T * info, Node* link=0): info_(info), link_(link)
{}
};
请注意,info_
现在是指向T
实例的指针。使用指针的想法是指定指针比复制复杂对象便宜。
答案 4 :(得分:1)
指向正在声明的类型的对象的指针在C和C ++中都很好。这是基于指针是固定大小的对象(例如,在32位平台上总是32位整数)的事实,因此您不需要知道指向类型的完整大小。
实际上,您甚至不需要完整的类型声明来声明指针。前瞻声明就足够了:
class A; // forward declared type
struct B
{
A* pa; //< pointer to A - perfectly legal
};
当然,在实际访问成员时,您需要在范围内进行完整声明:
#include <A.hpp> // bring in full declaration of class A
...
B b;
b.pa = &a; // address of some instance of A
...
b.pa->func(); // invoke A's member function - this needs full declaration
对于FIFO,请查看std::queue
。 std::list
,std::deque
和std::vector
都可用于此目的,但也可提供其他功能。