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