C++ 编写重载赋值运算符

C++ 编写重载赋值运算符,c++,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

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

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

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

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

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

让我举一个我认为您的
节点
设计应该是什么样子的示例:

第一级提供抽象接口:

 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() {}
 };
第三级提供具体实施


你读了吗?很难说应该为父母做些什么。没有通用规则,这完全取决于您的用例和您希望通过实现赋值运算符(和复制构造函数)实现的语义。因为您有一个额外的方法来设置
\u parent
成员,所以我认为将其初始化为
nullptr
将是最好的选择。@mickeyj失去了兴趣??抱歉被耽搁了。然而,我在想,如果它只是对内存位置的引用,那么只复制地址位置就可以了。当为对象调用析构函数时,它将使地址为空,但是不会删除内存位置,因为析构函数不会删除内存。实际上,我正在实现的不是链表。这只是我提出的一个例子,展示了这样一种情况:类中只存储了对对象的引用,而类中没有分配内存。内存分配是在classOK之外完成的,我的示例也没有提到链表,而是一个树实现。无法判断这是否为您的实际用例提供了任何建议。你可以试着让你的例子更“中立”,把你的问题切中要害!
 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);
     }
 }