C++ 复制类的构造函数,该类在C+中具有指向自身的自指针+;?

C++ 复制类的构造函数,该类在C+中具有指向自身的自指针+;?,c++,c++11,deep-copy,self-reference,this-pointer,C++,C++11,Deep Copy,Self Reference,This Pointer,我想问的是,我们如何实现一个类的拷贝构造函数,这个类的自指针指向它自己作为它的数据成员,我想实现一个深度拷贝 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;

我想问的是,我们如何实现一个类的拷贝构造函数,这个类的自指针指向它自己作为它的数据成员,我想实现一个深度拷贝

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


};
我不明白这一行
//如何分配父级
parent=new City(??
是否将再次调用构造函数而不是深度复制? 问候。

怎么样

if (obj.parent != NULL)
    parent = new City(*obj.parent)
else
    parent = NULL;
除非在父层次结构中有循环,否则这应该有效。

如何

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

除非在父层次结构中有循环,否则这应该是有效的。

克里斯蒂安的答案非常好

如果不使用空指针终止链,而是使用对self的引用终止链(是否使用“self-pointer-to-self”?),则可以执行以下操作:

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


};
class城市
{
字符串名;
城市*家长;
///循环引用情况下无限循环要避免的DB
静止的
标准::映射和父对象_db()
{static std::map ret;
返回ret;
}
///利用数据库的克隆功能
静止的
城市*克隆父对象(常数城市*父对象)
{if(_父项)
{City*&克隆的_parent=parents_db()[_parent];
如果(!克隆父对象)
克隆父对象=新城市(\u父对象);
返回克隆的父对象;
}
返回NULL;
}
///使用克隆函数的私有构造函数
城市(康斯特城市*obj):
名称(对象->名称),
父项(克隆父项(对象->父项))
{}
公众:
城市(串南,双dcov);
城市(字符串nam,双dcov,城市*c);
///克隆层次结构后清理数据库的公共构造函数
城市(康斯特城市和obj):
名称(对象名称),
父项(克隆父项(对象父项))
{parents_db().clear();
}
~City();
void setName(字符串名称1);
覆盖的无效设置距离(内部距离);
字符串getName();
双getDistanceCovered();
City*getParent(){return parent;}
};

克里斯蒂安的回答非常好

如果不使用空指针终止链,而是使用对self的引用终止链(是否使用“self-pointer-to-self”?),则可以执行以下操作:

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


};
class城市
{
字符串名;
城市*家长;
///循环引用情况下无限循环要避免的DB
静止的
标准::映射和父对象_db()
{static std::map ret;
返回ret;
}
///利用数据库的克隆功能
静止的
城市*克隆父对象(常数城市*父对象)
{if(_父项)
{City*&克隆的_parent=parents_db()[_parent];
如果(!克隆父对象)
克隆父对象=新城市(\u父对象);
返回克隆的父对象;
}
返回NULL;
}
///使用克隆函数的私有构造函数
城市(康斯特城市*obj):
名称(对象->名称),
父项(克隆父项(对象->父项))
{}
公众:
城市(串南,双dcov);
城市(字符串nam,双dcov,城市*c);
///克隆层次结构后清理数据库的公共构造函数
城市(康斯特城市和obj):
名称(对象名称),
父项(克隆父项(对象父项))
{parents_db().clear();
}
~City();
void setName(字符串名称1);
覆盖的无效设置距离(内部距离);
字符串getName();
双getDistanceCovered();
City*getParent(){return parent;}
};

我的意思是城市级ha City*家长作为其成员。我认为你需要对家长做一个深度复制。@LuchianGrigore看到代码我理解OP的意思,但这是一个可怕的问题标题…@πάνταῥεῖ 这是一个笑话,意思是城市级的哈市*家长作为其成员。我想你需要对家长做一个深度复制。@LuchianGrigore看到代码我理解OP的意思,但这是一个可怕的问题标题…@πάνταῥεῖ 那是个笑话