c++ - 复制构造函数和动态分配

标签 c++ operator-overloading copy-constructor assignment-operator

我想问你如何为以下类编写复制构造函数(和 operator = )。

Node 类存储每个节点的坐标 x,y 和指向另一个节点的指针。

class Node
{
private:
double x, y;
Node *n;

public:
Node (double xx, double yy, Node *nn) : x(xx), y(yy), n(nn) {}
void setNode (Node *nn) : n(nn) {} 
...
};

类NodesList(继承自std::vector)存储所有动态分配的Node

class NodesList : public std::vector<Node *>
{}

主程序:

int main()
{
Node *n1 = new Node(5,10,NULL);
Node *n2 = new Node(10,10,NULL);
Node *n3 = new Node(20,10,NULL);
n1->setNode(n2);
n2->setNode(n3);
n3->setNode(n2);
NodesList nl1;
nl1.push_back(n1);
nl1.push_back(n2);
nl1.push_back(n3);
//Copy contructor is used, how to write
NodesList nl2(nl1);
//OPerator = is used, how to write?
NodesList nl3 = nl1;

我不想为每个节点创建一个浅拷贝,而是为每个节点创建一个深拷贝。我可以向您索取带有复制构造函数的示例代码吗?

每个节点都可以指向多次。让我们有这样的情况,当 3 个节点 n[1]、n[2]、n[3] 存储在 NodesList nl1 中时:

n[1] 指向 n[2]

n[2] 指向 n[3]

n[3] 指向 n[2]

A] 我们的复制构造函数处理节点 n[1]。它创建一个新对象 n[1]_new,由旧对象 n[1]_old 的拷贝表示。 n[1]_old 指向的节点 n[2] 仍然不存在,所以 n[2]_new 也必须被创建... n1_new 指向 n2_new 的指针被设置。

B] 然后处理第二个点n[2]。不能创建两次,n[2]_new是在A]中创建的。但是指向的节点 n[3] 不存在,因此创建新对象 n[3]_new 作为旧对象 n[3]_old 的拷贝。从 n2_new 到 n3_new 的指针被设置。

C] 节点 n[3]_new 已经创建,n[2]_new。从 n3_new 到 n2_new 的指针已设置,不会创建其他对象...

所以复制构造函数应该检查对象是否在过去被创建过...

一些引用计数可能会有所帮助...

最佳答案

这是我的问题解决方案。添加了一个新的数据成员 n_ref 存储节点 n 的新版本:

class Node
{
private:
double x, y;
Node *n, *n_ref;

public:
Node (double xx, double yy, Node *nn) : x(xx), y(yy), n(nn) {n_ref = NULL;}
Node * getNode() {return n;}
Node * getRefNode () {return n_ref;}
void setNode (Node *nn) {this->n = nn;} 
void setRefNode (Node *nn) {this->n_ref = nn;}

复制构造函数创建节点的浅拷贝:

Node (const Node *node) 
{
    x = node->x;
    y = node->y;
    n = node->n;
    n_ref = node->n_ref;
}

NodesList 的复制构造函数

    NodesList::NodesList(const NodesList& source)
    {
        const_iterator e = source.end();
        for (const_iterator i = source.begin(); i != e; ++i) {

            //Node* n = new Node(**i);

            //Node n still has not been added to the list
            if ((*i)->getRefNode() == NULL)
            {
                //Create node
                Node *node = new Node(*i);

                //Add node to the list
                push_back(node);

                //Set this note as processed
                (*i)->setRefNode(node);

                //Pointed node still has not been added to the list
                if ((*i)->getNode()->getRefNode() == NULL)
                {
                    //Create new pointed node
                    Node *node_pointed = new Node ((*i)->getNode());

                    //Add node to the list
                    push_back(node_pointed);

                    //Set pointer to n
                    node->setNode(node_pointed);

                    //Set node as processed
                    ((*i)->getNode())->setRefNode(node_pointed);
                }

                //Pointed node has already been added to the list
                else
                {
                    //Set pointer to node n
                    node->setNode((*i)->getRefNode());
                }
            }

            //Node n has already been added to the list
            else
            {
                //Get node
                Node * node = (*i)->getRefNode();

                //Pointed node still has not been added
                if ((*i)->getNode()->getRefNode() == NULL)
                {
                    //Create new node
                    Node *node_pointed = new Node ((*i)->getNode());

                    //Add node to the list
                    push_back(node_pointed);

                    //Set pointer to n
                    node->setNode(node_pointed);

                    //Set node as processed
                    ((*i)->getNode())->setRefNode(node_pointed);
                }

                //Pointed node has already been added to the list
                else
                {
                    //Set pointer to n
                    node->setNode((*i)->getNode()->getRefNode());
                }
            }
        }
    }

关于c++ - 复制构造函数和动态分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2392318/

相关文章:

c++ - 类切片导致的未处理异常

c++ - c++修改basic_ostream对象的内容,或者,删除basic_ostream对象的数据内容

C++编译器如何合成默认的拷贝构造函数

c++ - 我可以对 2 个外观相似的类使用类型转换运算符吗?

静态对象的 C++ 复制构造

c++ - 如何为具有内部放置 new 的类实现安全复制构造函数(使用 std::string)

c++ - 对内联行为 C++ 的困惑

c++ - cpp 文件的 osx coretext header ,10.8 之前?

c++ - 在赋值运算符之前调用结构的析构函数

c++ - 如何在它之外的模板类中使用模板参数?