编写重载的赋值运算符

时间:2013-10-17 17:00:55

标签: c++

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

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?
}

1 个答案:

答案 0 :(得分:0)

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

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

另外,我会避免在(至少)生产代码中使用原始指针。您应该使用std::shared_ptralike

让我举一个例子,我认为你的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() {}
 };

第二级提供基本实施:

 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);
     }
 }