【问题标题】:Alternative of public setter methods公共设置方法的替代方法
【发布时间】:2014-03-19 03:09:49
【问题描述】:

给定一个名为 AVLNode 的类,其中包含树的节点描述,

template<typename T>
class AVLNode
{
 public:
    AVLNode(T, AVLNode<T>*, AVLNode<T>*, int);
    ~AVLNode();
    void setLeft(AVLNode<T>*);
    AVLNode<T>* getLeft() const;
    void setRight(AVLNode<T>*);
    AVLNode<T>* getRight() const;
    void setHeight(int);
    void setKey(const T& );
    int getHeight() const;
    const T& getKey() const;

  private:
    T key;
    AVLNode<T> *left;
    AVLNode<T> *right;
    int height;
  };

以及类 AVLTree 中的以下旋转方法。

template<typename T>
AVLNode<T>* AVLTree<T>::rotateRight(AVLNode<T> *node1)
 {
   AVLNode<T> *node2 = node1->getLeft();
   AVLNode<T> *T2 = node2->getRight();

   // Perform rotation
   node2->setRight(node1);
   node1->setLeft(T2);

  // Update heights
   node1->setHeight(max(height(node1->getLeft()), height(node1->getRight()))+1);
   node2->setHeight(max(height(node2->getLeft()), height(node2->getRight()))+1);

  // Return new root
   return node2;
 }

有没有办法在没有公共 setter 方法的帮助下设置这些?那就是我可以使用私有方法或其他技术来实现这一点,以便客户端代码不能更改属性(除非并且直到真正需要操作)?如何最大限度地隐藏数据并减少耦合?

编辑:我不想使用公共 setter 方法。有没有其他方法来操作(设置)私有属性? IE; AVLNode 对象如何在不使用公共 setter 方法的情况下设置其私有属性?

【问题讨论】:

  • 我写C++已经有一段时间了,但我相信你所说的概念是“朋友”。 yosefk.com/c++fqa/friend.html
  • 我没有考虑使用朋友关系。请参阅最后一部分:问题的“编辑”。明确的问题写在那里。
  • 你问有没有其他方法,然后拒绝显而易见的答案。您希望 setter 不公开,但您希望有特权的类可以访问它。那是一个朋友。唯一的其他选择是在这种情况下没有意义的子类化。您还可以将验证代码添加到设置器以使其“更安全”。我认为你过于谨慎了。如果有人添加了“恶意”代码,那么他们就会破坏代码,那就是问题
  • 感谢@Spidy,是的,我将使用朋友。它最适合这里。

标签: c++ data-structures binary-search-tree avl-tree


【解决方案1】:

我认为您有一些名为 AVLTree 或类似名称的容器。

如果是这样,我会定义一个类:

template <typename T>
class AVLNode
{
  protected:   
    T key;
    AVLNode<T>* left;
    AVLNode<T>* right;
    int height;

  public:
    AVLNode<T>* getRight() const { return right: }
    AVLNode<T>* getLeft()  const { return left;  }
};

template <typename T>
class WritableAVLNode : public AVLNode<T>
{
   public:
      void setRight(AVLNode<T>* right) { AVLNode<T>::right = right; }
      void setLeft(AVLNode<T>* left)   { AVLNode<T>::left = left; }
};

所有内部类都可以使用 WritableAVLNode,但这些方法将只公开只读版本:AVLNode。

【讨论】:

  • 如果我在 AVLTree 中定义了 struct AVLNode,那么问题也没有解决。 AVLTree 对象可以在公共方法中访问 AVLNode 的属性,方法是使用 struct AVLNode 类型变量访问左、右、键等属性。我关心的是限制对属性的访问。仔细查看问题的最后一部分(“编辑”)。
【解决方案2】:

如果您希望AVLTree 能够访问AVLNode 的私有或受保护成员,您可以使用friend 声明。这将假定树和节点使用相同的类型。

template <typename T>
class AVLNode
{
    friend class AVLTree<T>;    
};

【讨论】:

  • 我不需要 AVLTree 成为 AVLNode 的朋友类。我只想知道是否有任何可能的方法可以帮助我的应用程序让 AVLNodes 不使用公共设置方法直接修改私有属性。简单地说,我不想使用公共 setter 方法。还有其他方法可以操作(设置)私有属性吗?
  • 您可以将成员公开,编写修改值的方法或声明类的朋友。这就是语言的工作方式。我看不出你想要完成什么。
  • 是的,我确实做到了——我已经定义了一些修改私有属性的公共设置方法。作为参考,您可以查看 AVLNode 类。但是使用公共 setter 方法可能会使程序不一致,正如您在“rotateRight”方法中看到的那样,如果引入了任何漏洞,那么易受攻击的代码可以在任何可用的对象上调用任何 setter 方法[考虑到最坏的情况]。这就是为什么我要问那里是否有其他方法。我也不知道有没有。
猜你喜欢
  • 2014-09-21
  • 2011-04-19
  • 2020-09-22
  • 1970-01-01
  • 2015-10-01
  • 2018-02-03
  • 1970-01-01
  • 1970-01-01
  • 2018-09-27
相关资源
最近更新 更多