如何使用智能指针为单链表实现复制构造函数
How to implement a copy constructor for a singly linked list utilizing smart pointers
这是我第一次真正在这里发布问题!我在为单链表创建复制构造函数时遇到了一些问题。我在这个网站和其他各种网站上到处搜索了一个可比较的例子,但无济于事。我试图使用智能指针,但到目前为止只使用了 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);
}
}
更新#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);
}
}
}
您没有 post 太多关于您的 Deque
或 Node
类 实际长什么样的信息。根据从您的代码片段中看到的信息,您的主要问题是您使用 std::unique_ptr<T>
来导航您的列表:那是行不通的:每当分配或销毁非空 std::unique_ptr<T>
时,它都会释放持有的对象。您将需要一个非拥有指针。
由于您没有 post 太多上下文信息,我无法轻松测试此代码是否有效,但我认为它应该没问题:
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 来维护开始的节点的目的。
这是我第一次真正在这里发布问题!我在为单链表创建复制构造函数时遇到了一些问题。我在这个网站和其他各种网站上到处搜索了一个可比较的例子,但无济于事。我试图使用智能指针,但到目前为止只使用了 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);
}
}
更新#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);
}
}
}
您没有 post 太多关于您的 Deque
或 Node
类 实际长什么样的信息。根据从您的代码片段中看到的信息,您的主要问题是您使用 std::unique_ptr<T>
来导航您的列表:那是行不通的:每当分配或销毁非空 std::unique_ptr<T>
时,它都会释放持有的对象。您将需要一个非拥有指针。
由于您没有 post 太多上下文信息,我无法轻松测试此代码是否有效,但我认为它应该没问题:
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 来维护开始的节点的目的。