在C 中具有自我点的类的复制构造函数

copy constructor of a class which has self-pointer to itself in C++?

本文关键字:复制 构造函数 自我      更新时间:2023-10-16

我想问,我们将如何实现一个具有自我指针自身作为数据成员的类的复制构造函数,我想实现一个深层副本,

class City
{
    string name;
    City* parent;
public:
    City(string nam, double dcov);
    City(string nam, double dcov, City* c);
City(const City& obj)
{
    this-> name = obj.name;
// how to assign parent 
parent = new City(??)
}
    ~City();
    void setName(string name1);
    void setDistanceCovered(int dist);
    string getName();
    double getDistanceCovered();
    City* getParent(){return parent;}

};

我感到困惑的是,这条线// how to assign parent parent = new City(??)会再次调用构造函数,而不是深副本?问候。

怎么样
if (obj.parent != NULL)
    parent = new City(*obj.parent)
else
    parent = NULL;

除非您在父层次结构中有周期。

克里斯蒂安的答案非常好。

如果您不用零指针终止链,而是对自我的引用(是您试图用"自我指针自身"来说的?),您可以这样做:

if(obj.parent == NULL)
    parent = NULL;
else if(obj.parent==&obj)
    parent=this;
else parent = new City(*obj.parent);

如果您有要避免的周期,则需要使用临时注册地图:

class City
{
    string name;
    City* parent;
    /// The DB to avoid for infinite loops in case of circular references
    static
    std::map<const City*,City*>& parents_db()
    {   static std::map<const City*,City*> ret;
        return ret;
    }
    /// The cloning function that make use of the DB
    static
    City* clone_parent(const City *_parent)
    {   if(_parent)
        {   City *& cloned_parent = parents_db()[_parent];
            if(!cloned_parent)
               cloned_parent = new City(_parent);
            return cloned_parent;
        }
        return NULL;
    }
    /// The private constructor that make use of the cloning function
    City(const City* obj) :
        name(obj->name),
        parent(clone_parent(obj->parent))
    {}
public:
    City(string nam, double dcov);
    City(string nam, double dcov, City* c);
    /// The public constructor that cleans up the DB after cloning the hierarchy
    City(const City& obj) :
        name(obj.name),
        parent(clone_parent(obj.parent))
    {   parents_db().clear();
    }
    ~City();
    void setName(string name1);
    void setDistanceCovered(int dist);
    string getName();
    double getDistanceCovered();
    City* getParent(){return parent;}

};