考虑下面的类定义,我有一个关于重载赋值运算符应该是什么样的问题。
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?
}
答案 0 :(得分:0)
这不是一个真正的答案,而是关于您的设计方法的另一个问题:
显然你正试图设计一个树节点,对吧?
为什么要在节点中存储父类,反之亦然(即保存子节点实例或指针的std::vector
)。这将简化分配(复制)的语义。当然,您需要添加/删除/清除子节点的方法,设置_parent
成员应该在添加/删除实现内部完成。节点的树叶实现只为这个功能提供空方法。我还要添加另一个间接级别,并将Node
声明为纯抽象类并提供s.th.例如ContainerNodeBase
和LeafNodeBase
作为第一级实施。
另外,我会避免在(至少)生产代码中使用原始指针。您应该使用std::shared_ptr
或alike。
让我举一个例子,我认为你的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);
}
}