0

考虑下面的类定义,我有一个关于重载赋值运算符应该是什么样子的问题。

class Node{
public:
    void setName(string name) { _name = name;}
    void setParent(Node * n) {_parent = n;}
private:
    string _name;
    Node* _parent;
}


main()
{
  vector <Node*> nodes;
  Node * n1 = new Node();
  n1->setName("a");
  n1->setParent(NULL);

  Node *n2 = new Node();
  n2->setName("a");
  n2->setParent(n1);

  Node *n3;
  *n3 = *n2; 
}

我的问题是,Node 类的重载赋值运算符应该是什么样子。

Node & operator = (const &n)
{
  if(this == &n)
   return *this;
  _name = that._name;
  _parent = new Node(); // Should this be done?
  _parent(that.parent); //Should this done?
}
4

1 回答 1

0

这不是一个真正的答案,而是关于您的设计方法的另一个问题:

显然你正在尝试设计一个树节点,对吧?
为什么将父类存储在节点中而不是相反(即持有std::vector子节点实例或指针)。这将大大简化分配(复制)的语义。当然,您需要依次添加/删除/清除子节点的方法,然后设置_parent成员应该在添加/删除实现内部完成。节点的树叶实现只会为此功能提供空方法。另外我会添加另一个级别的间接并声明Node为纯抽象类并提供s.th。喜欢ContainerNodeBaseLeafNodeBase作为第一级实施。

此外,我会避免在(至少)生产代码中使用原始指针。你应该使用std::shared_ptr类似的。

让我举个例子,我认为你的Node设计应该是什么样子:

第一级提供抽象接口:

 struct INode
 {
     virtual const std::string & name() const = 0;
     virtual void name(const std::string& value) = 0;
     virtual INode* parent() const = 0;
     virtual ~INode() {}
 };

 struct INodeCotainer
 {
     virtual void add(std::shared_ptr<INode> child) = 0;
     virtual void remove(const INode* child) = 0;
     virtual void clear() = 0;
     virtual const std::vector<std::shared_ptr<INode>>& childs() const = 0; 
     virtual ~INodeCotainer() {}
 };

2级提供基础实现:

 class NodeBase
 : public INode
 {
 public:
     virtual const std::string & name() const { return name_; }
     virtual void name(const std::string& value) { name_ = value; }
     virtual INode* parent() const { return parent_; }

 protected: // protect this class from direct instantiation
     NodeBase() {}
     NodeBase(const NodeBase& rhs) { parent_ = nullptr; name_ = rhs.name; }
     NodeBase& operator=(const NodeBase& rhs) 
     { 
        if(&rhs != this)
        {
            parent_ = nullptr; name_ = rhs.name;
        }
        return *this;
     }

     INode* parent_;

 private:
     std::string name_;
 };

第三级提供具体实施

 class ContainerNode
 : public NodeBase
 , public INodeContainer
 {
 public:
     ContainerNode() : NodeBase {}
     ContainerNode(const ContainerNode& rhs) : NodeBase(rhs) 
     {
         std::copy(childs_,rhs.childs_);
     }
     ContainerNode& operator=(const ContainerNode& rhs)
     {
         NodeBase::operator=(rhs);
         childs_.clear();
         std::copy(childs_,rhs.childs_);
     }

     virtual void add(std::shared_ptr<INode> child) 
     { 
         childs_.push_back(child);
         childs_.back()->parent_ = this;
     }         
     virtual void remove(const INode* child)
     {
         // Find the child reference in the childs_ vector remove it 
         // and set it's parent_ member to nullptr
     }
     virtual void clear() { childs_.clear(); }
     virtual const std::vector<std::shared_ptr<INode>>& childs() const
         { return childs_; }

 private:
     std::vector<std::shared_ptr<INode>> childs_;
 }

 class LeafNode
 : public NodeBase
 {
 public:
     LeafNode() : NodeBase {}
     LeafNode(const LeafNode& rhs) : NodeBase(rhs) {}
     LeafNode& operator=(const LeafNode& rhs)
     {
         NodeBase::operator=(rhs);
     }
 }
于 2013-10-17T18:47:33.217 回答