gpt4 book ai didi

c++ - 关于手动内存管理和深度复制的新手问题

转载 作者:太空宇宙 更新时间:2023-11-03 10:22:23 25 4
gpt4 key购买 nike

好吧,这是我第一次尝试 C++,因为看起来我将不得不在即将到来的大学类(class)中使用它。我有几年的编程经验,但在非垃圾收集领域并不多。

我有一个类,一个用于双向链表的节点。所以基本上它有一个值和两个指向其他节点的指针。主构造函数看起来像 Node(const std::string & val, Node * prev, Node * next)。该练习包括一个复制构造函数,该复制构造函数执行另一个节点的浅拷贝,上面有一条注释,说明将其更改为进行深拷贝。

这是我认为的意思:

Node(const Node & other)
: value(other.value)
{
prev = new Node(other.prev->value, other.prev->prev, other.prev->next);
next = new Node(other.next->value, other.next->prev, other.next->next);
}

这似乎实现了使更改复制的节点不会影响新节点的目标。但是,当我这样做时,我正在堆上分配新的东西。这让我很担心,因为我认为这意味着我也应该在 Node 的析构函数中删除它。但这现在与其他构造函数不一致,其中指向节点的指针只是传入,已经指向了一些东西。我不能在析构函数中正确地 deleteing nextprev,对吗?

我真的很困惑,感谢指导!

编辑:这是代码(在我对它进行上述更改之前),按照要求:

#include <string>

//! Node implements a doubly-linked list node
class Node {
friend class LinkedList; //!< LinkedList can access private members of Node
public:

//! Constructor
Node(const std::string & v, Node * p, Node * n) :
value(v), prev(p), next(n)
{
}

//! Change to deep copy
Node(const Node & other) :
value(other.value), prev(other.prev), next(other.next)
{
}

//! Read-only public methods for use by clients of the LinkedList class
const std::string & GetValue() const
{
return value;
}


Node * GetPrevious()const
{
return prev;
}


Node * GetNext()const
{
return next;
}

//! Change to deep copy
Node & operator=(const Node & other)
{
if(this!=&other)
{
value=other.value;
prev=other.prev;
next=other.next;
}
return *this;
}

private:
std::string value; //!< value stored in the node
Node * prev; //!< pointer to previous node in the list
Node * next; //!< pointer to next node in the list
};

最佳答案

首先,我不太确定应该如何理解练习的目标。文案应该有多深?在像您这样的解决方案中,this->next->nextother.next->next 仍然是同一件事。这个对象也应该被复制吗?名单的其余部分呢?它在哪里结束?人们当然可以深度复制整个列表,但我认为这对于单个节点的复制构造函数来说是一种非常出乎意料的行为。

也许 value 成员变量是一个指针,应该被深度复制?这对我来说更有意义。

但是回到你的解释:

Node a(...);
// ... more code that adds a whole list to a
Node b(a);

您的实现存在两个问题。对于一个 b->next->prev 指向 a,而我怀疑它应该指向 b。其次,您需要考虑极端情况,其中 a 可能是列表中的第一个或最后一个节点。

关于您的主要问题:您当然是对的,新创建的对象需要在某处再次deleted。无论您只是复制 prevnext 节点还是整个列表,我会说该拷贝的用户有责任再次删除所有复制的节点。我假设使用一个正常的、未复制的列表,该列表的用户将遍历所有节点并在完成列表后一个接一个地手动删除它们。他不会假设一个节点的析构函数删除整个列表。拷贝也是如此,它们的行为应该相同。复制的东西的用户应该删除所有的拷贝。 (实际上,您可能有一个 list 类,它会为您完成所有节点管理工作)。

但是,如果节点的复制构造函数复制整个列表,甚至只是其中的几个节点,这将是非常出乎意料的,而且人们总是会忘记清理所有这些拷贝。但这不是你的节点类的错,而是练习要求的错。

关于c++ - 关于手动内存管理和深度复制的新手问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/468134/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com