【问题标题】:FIFO implementation先进先出实现
【发布时间】:2010-06-13 19:20:25
【问题描述】:

在实现 FIFO 时,我使用了以下结构:

struct Node
{
    T info_;
    Node* link_;
    Node(T info, Node* link=0): info_(info), link_(link)
    {}
};

我认为对于许多 STL 容器(例如 List)来说,这是一个众所周知的技巧。这是一个好习惯吗?当您说 Node 有一个类型为它的指针的成员时,这对编译器意味着什么?这是一种无限循环吗?

最后,如果这是一个不好的做法,我该如何实现更好的 FIFO。

编辑:人们,这都是关于实施的。我对 STL 库足够熟悉,并且知道来自多个库的大量容器。只是我想与可以提供良好实施或良好建议的人讨论。

【问题讨论】:

    标签: c++ implementation fifo


    【解决方案1】:

    这是一个好习惯吗?

    我看不出有什么特别的问题。

    当你说 Node 有一个类型为它的指针的成员时,这对编译器意味着什么?

    类存储指向同一类对象的指针并没有错。

    最后,如果这是一种不好的做法,我该如何实现更好的 FIFO。

    我会使用std::queue ;)

    【讨论】:

      【解决方案2】:

      显然,您使用链表作为队列的底层实现。没有什么特别糟糕的。

      仅供参考,就实现而言,std::queue 本身使用 std::deque 作为其底层实现。 std::deque 是一种更复杂的数据结构,由巧妙管理的动态数组块组成。 它最终比链表更好,因为:

      1. 对于链表,每次插入都意味着您必须进行昂贵的动态内存分配。使用动态数组,您不需要。仅当缓冲区必须增长时才分配内存。
      2. 数组元素是连续的,这意味着可以在硬件中轻松缓存元素访问。

      【讨论】:

        【解决方案3】:

        指向正在声明的类型对象的指针在 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::queuestd::liststd::dequestd::vector 都可以用于此目的,但也可以提供其他设施。

        【讨论】:

          【解决方案4】:

          您可以使用现有的 FIFO,std::queue

          【讨论】:

          • 这是关于实施的。我知道在哪里可以找到一个好的容器;)。
          • @Narek:我觉得会是这样,但没有时间写更多内容:) 我同意其他 cmets - 你的实现没有问题,但是使用 @ 987654322@ 性能会更好。
          【解决方案5】:

          这是实现节点的一种好方法。节点指针用于创建指向容器中下一个节点的链接。你是对的,它可以用来创建一个循环。如果容器中的最后一个节点引用了第一个节点,则迭代该容器将遍历所有节点。

          例如,如果容器是 FIFO 队列,则指针将引用队列中的下一个节点。也就是说,link_ 的值将是类Node 的另一个实例的地址。

          如果值类型T 实现了一个昂贵的复制构造函数,一个更高效的Node 类将是

          struct Node
          {
              T * info_;
              Node* link_;
              Node(T * info, Node* link=0): info_(info), link_(link)
              {}
          };
          

          请注意,info_ 现在是指向T 实例的指针。使用指针背后的想法是分配指针比复制复杂对象的成本更低。

          【讨论】:

          • 好的,但是指针会带来所有权问题。现在谁负责删除info
          猜你喜欢
          • 1970-01-01
          • 2020-01-15
          • 2021-05-23
          • 1970-01-01
          • 1970-01-01
          • 2015-05-02
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多