簡體   English   中英

編寫重載的賦值運算符

[英]Writing an overloaded assignment operator

考慮下面的類定義,我有一個關於重載的賦值運算符應該是什么樣子的問題。

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

這不是真正的答案,而是關於您的設計方法的另一個問題:

顯然您正在嘗試設計樹節點,對嗎?
為什么要在節點中存儲父類,而不是相反(例如,持有子節點實例或指針的std::vector )。 這將大大簡化分配(復制)的語義。 您當然需要依次添加/刪除/清除子節點的方法,然后應在add / remove實現內部在內部設置_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() {}
 };

第二層提供基本實施:

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM