这是我第一次在这里发布问题!我在为单链表创建复制构造函数时遇到了一些麻烦。我在这个和其他各种网站上搜索了一个类似的例子,但无济于事。我试着使用智能指针,到目前为止,我只使用了unique_ptr(s)
。这个函数的目的是对传递给它的链表进行深度复制。我已经尝试了以下到目前为止,但我只得到一个段故障。我已经运行了一些测试,我相信我的insert_front()
和insert_back()
功能工作良好。如果有帮助的话,我确实有指向头部和尾部的指针。下面是我试过的代码。
Deque::Deque(const Deque& deque2copy){
this -> head = 0;
unique_ptr<Node> temp = make_unique<Node>(deque2copy.head -> val, move(deque2copy.head->next));
while(temp != 0){
this ->insert_back(temp->val);
temp = move(temp-> next);
}
}
UPDATE # 1
Deque::Deque(const Deque& deque2copy){
if(deque2copy.head->next == nullptr){
return;
} else {
this -> head = 0;
unique_ptr<Node> temp = make_unique<Node>(*deque2copy.head->next);
while(temp != 0){
this ->insert_back(temp->val);
temp = move(temp-> next);
}
}
}
您没有发布多少关于您的Deque
或Node
类实际上看起来确切的信息。根据您的代码片段浏览的信息,您的主要问题是您使用std::unique_ptr<T>
来导航您的列表:这将不起作用:每当分配或销毁非空std::unique_ptr<T>
时,它将释放持有的对象。你需要一个非归属的指针。
因为你没有发布太多的上下文信息,我不能很容易地测试这段代码是否有效,但我认为它应该是好的:
Deque::Deque(const Deque& deque2copy)
: head() { // the default constructor does the null-initialization
std::unique_ptr<Node>* tail(&this->head);
for (Node* temp(deque2copy.head.get()); temp; temp = temp->next.get()) {
*tail = std::make_unique<Node>(temp->value);
tail = &tail->next;
}
}
请注意,这段代码使用非所属指针导航两个列表:
- 对于源列表,它使用从
std::unique_ptr<Node>::get()
获得的Node*
来避免在分配或销毁std::unique_ptr<Node>
时破坏Node
对象。 - 为目标列表保留指向列表中当前最后一个
std::unique_ptr<Node>
的指针tail
(最初是head
,一旦分配到列表中的最后一个next
指针),以有效地追加节点。
代码假设Node
有一个以value
作为构造函数参数的构造函数。这个构造函数将相应地初始化value
成员,并默认初始化next
成员,例如:
Node::Node(T const& value)
: value(value)
, next() {
}
请注意,对列表中的元素使用所属指针通常是一个坏主意:head的析构函数将递归地调用列表中所有节点的析构函数。根据析构函数的实际编写方式,这种递归可能很容易造成堆栈溢出。为了解决这个问题,您需要为列表编写一个自定义析构函数来避免这种递归。但是,这样做完全违背了使用 std::unique_ptr
s来维护初始节点的目的。