【问题标题】:Defining a Node in a class and outside of class在类中和类外定义节点
【发布时间】:2018-02-05 18:28:37
【问题描述】:

Header-File-1 和 Header-File-2 的区别对程序(用 C++ 编写)有何影响?

哪个是更好的编码实践?

感谢您提前回复。

头文件-1

#ifndef BST 
#define BST

#include<cstdlib>

class BST{

struct Node{

    DataType dataIn;
    Node * rigth;
    Node * left;
};
     public:
         BST();
        ~BST();
         Node * insert(DataType dataIn);
         Node * remove(DataType dataOut);
         Node * search(DataType dataSearch);
         void printTree();
     private:
         Node * root;
} 
#endif

头文件-2

#ifndef BST 
#define BST

#include<cstdlib>

struct Node{

    DataType dataIn;
    Node * rigth;
    Node * left;
};

class BST{
     public:
         BST();
        ~BST();
         Node * insert(DataType dataIn);
         Node * remove(DataType dataOut);
         Node * search(DataType dataSearch);
         void printTree();
     private:
         Node * root;
} 
#endif

【问题讨论】:

  • using namespace std; 总是不好
  • “哪个是更好的编码实践?” 是基于意见的,它们都有潜在的用例
  • 如果在header1中将Node的定义设为public,那么差别不大。如果它是私有的,BST 的用户将很难使用从您的方法返回的指针
  • @UnholySheep “使用命名空间标准;总是不好的”。一般还是在头文件里?
  • 不相关,我会花相当多的时间思考面向公众的 insertremovesearch 函数,所有这些函数都期望 root 作为第一个参数,其中私有root 成员变量已经提供了它们在概念上应该在来自外部调用的初始条目(假设它们是递归的)时使用的唯一初始根。简而言之,在面向公众的成员函数中不应该需要这些参数。该设计问题存在于 both 标题中。

标签: c++ object-oriented-analysis


【解决方案1】:

在第一个标头中struct Node 是类私有的,而在第二个标头中它是公共顶级struct

这意味着第一个标题的Node 是无用的:如果你要写这样的东西

BST::Node *n = bst.search(nullptr, DataType());

代码无法编译:

错误:struct BST::Node 在此上下文中是私有的

公开struct Node 可以解决这个问题。这将是对第二个标头的轻微改进,因为它表明 NodeBST 的接近度。

但是,这并不理想,因为Node 仍然暴露在BST 的外部。这是次优的,因为实现细节对类外部可见。更好的方法是在BST 类中将Node 设为私有,并更改API,使Node 永远不会从BST 外部访问。这可以通过使用BST 类的root 实例变量来实现。

【讨论】:

  • 感谢您的回答。你的意思是我根本不应该返回 Node *,因为用户可以达到这三个。那我只能返回真假。我说的对吗?
  • @grahamScan 您可以返回一个公共迭代器类,或遵循std::map 中使用的模式并返回一对指示插入时发生的情况,并为您提供附加信息以防万一更换。同样,您可以在删除等时返回旧值。
  • 你能给我一个使用公共迭代器类的例子吗?我找不到它。当我将节点定义放在类中时,出现错误:未知类型名称“节点”。
【解决方案2】:

如果您的程序仅使用一种树(在您的情况下:BST),那么在两种情况下都是相同的;要么在 BST 类内部声明它,要么在外部声明它并使用包含。

  • 如果你的程序处理不同种类的树,那么你应该在 BST 之外声明它是可重用的,例如:

    struct Node{
        DataType dataIn;
        Node * rigth;
        Node * left;
    };
    
    class rootedBT {
        public:
    
        private:
           Node* R;
           Node* L;
           T data;
    };
    
    class fullBT {
        public:
    
        private:
           Node* R;
           Node* L;
           T data;
     };
    
  • 在标题中也使用using namespace std 真的很可怕。

  • 一个类的成员数据默认是private,所以你的class Node默认是私有的,而不是struct

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多