【问题标题】:Where to declare the Node structure when implementing a List in C++在 C++ 中实现 List 时在哪里声明 Node 结构
【发布时间】:2014-03-26 05:09:54
【问题描述】:

当我遇到这个问题时,我想出了两个选择。

第一个是在 List 类中声明 Node 结构。就像:

class List
{
    private:
          struct Node
          {
              int data;
              Node* next; 
          }
          Node* head;
          //...
    public:
           //....
}

对于这个,效果很好。公共区域的功能可以利用Node结构中的所有元素进行插入、删除等操作。另外,这会阻止用户直接使用 Node 结构(我认为如果我们在 List 中声明 Node,其他人无法使用此结构。是真的吗?)。但是,如果这个 Node 很通用,也会被 Stack、Queue 等使用,我们每次都要声明它。这很不方便。另外,如果我想实现一些适用于 List 的算法(例如排序),是否可以在不使用 Node 结构的情况下做到这一点?

第二种选择是实现一个Node类:

class Node
{
    private:
           int data;
           Node* next;
           //...
    public:
           //...
} 

class List
{
    private:
           Node* head;
           //...
    public:
           //...
}

这个不起作用,因为我无法使用类 List 的公共区域中的函数更改 Node 中的指针和数据。如果我把datanext放在类Node的public区域,恐怕用户也可以直接改指针,销毁链表。

人们在实现 List 时通常会做什么?提前感谢您的建议:-)

【问题讨论】:

  • 他们两者都不做,因为他们没有重新发明*。他们使用std::list<>,通常甚至不使用std::vector<>std::deque<>。也就是说,除非您必须将节点公开为外部实体或将其作为它们的“节点”类型与其他类共享,否则几乎没有理由使其独立。

标签: c++ list nodes


【解决方案1】:

在库代码开发中,将这些类型的“帮助”类(和函数)放在“详细”命名空间中是惯例,例如:

namespace my_library {

namespace detail {

class Node
{
    public:
           int data;
           Node* next;
           //...

           //...
} 

}

class List
{
    private:
           detail::Node* head;
           //...
    public:
           //...
}

}

按照惯例,任何查看或使用您的库的人都应该知道“详细”命名空间(或子命名空间)中的任何内容都“不适合公众使用”,可以这么说。您还可以更进一步,将帮助程序类放在另一个标题中(如“List_detail.h”)以进一步“隐藏”它们。此外,在生成库的文档时(例如,使用 doxygen),您应该跳过/省略/隐藏“详细”命名空间(或子命名空间)中的任何声明。

如果合适(在链接方面),您也可以将它们放置在未命名的命名空间中。

法令(在编码指南中)有时会避免嵌套类,因为并非所有编译器(主要是旧的不符合标准的编译器)都能很好地处理它们。

【讨论】:

    【解决方案2】:

    我的建议是首先将 Node 设为私有的、嵌套在 List 中的 struct。如果需要重用它,您可以将它移到List 之外。到时候你就得把Node的数据公开,或者对数据提供公开的get和set方法。

    【讨论】:

      【解决方案3】:

      你可以把你的节点类放在单独的头文件 node.h 中

      class Node
      {
          private:
                 int data;
                 Node* next;
          friend class List;
          friend class Stack; 
          friend class Queue;          
          public:
                 Node(int num):data(num), next(NULL)
                 {
                 }
                 int getData()
                 {
                      return data;
                 }
      };
      
      
      #include <node.h>
      
      class List
      {
          private:
                 Node* head;
          public:
      };
      

      【讨论】:

        最近更新 更多