List.h:
#pragma once
#include <iostream>
#include <memory>
#include <initializer_list>
class List{
public:
List();
List(const std::initializer_list<int> &list);
~List();
int size() const;
void push_back(int val);
void pop_back();
void pop_front();
friend std::ostream &operator << (std::ostream &os, const List &l);
private:
void printNodes() const;
struct Node {
Node(int data) : data(data) {}
std::unique_ptr<Node> next;
Node *previous;
int data;
};
int len;
std::unique_ptr<Node> head;
Node *tail;
};
List.cpp
#include "List.h"
List::List() : len(0), head(nullptr), tail(nullptr){
}
List::List(const std::initializer_list<int> &list) : len(0), head(nullptr), tail(nullptr) {
for (auto &elem : list)
push_back(elem);
}
List::~List() {
}
void List::push_back(int val){
if (tail == nullptr) {
head = std::make_unique<Node>(val);
tail = head.get();
head->next = nullptr;
head->previous = nullptr;
len++;
}
else {
tail->next = std::make_unique<Node>(val);
(tail->next)->previous = tail;
tail = tail->next.get();
tail->next = nullptr;
len++;
}
}
void List::pop_back(){
if(len == 1){
auto node = head.release();
delete node;
head = nullptr;
tail = nullptr;
}else{
// tail->previous;
}
}
void List::pop_front(){
if(len == 1){
auto node = head.release();
delete node;
head = nullptr;
tail = nullptr;
}else{
}
}
void List::printNodes() const{
Node *temp = head.get();
while (temp != nullptr) {
std::cout << temp->data << "\n";
temp = (temp->next).get();
}
}
int List::size() const{
return len;
}
std::ostream &operator<<(std::ostream & os, const List & l){
l.printNodes();
return os;
}
Source.cpp
#include <iostream>
#include "List.h"
using namespace std;
int main() {
List l{3, 5, 1, 6, 7};
cout << l << endl;
}
Hello Stack Overflow,我是一名数据结构专业的学生,作为练习,我正在尝试使用智能指针重新创建std::list
。根据我的阅读,看来unique_ptr
应该是默认使用的语言,shared_ptr
和weak_ptr
仅在unique_ptr
由于速度差异而不能使用的情况下使用。不幸的是,在尝试实现pop_back()
和pop_front()
时遇到了麻烦。我是否必须采用共享指针来完成整个std :: list的重新实现,还是可以使用唯一指针来完成这些功能?
答案 0 :(得分:0)
是的,这完全有可能。让我们从pop_back
开始:
您已经有一个指向tail
的节点的指针,但这并不是一个有趣的指针,因为它只是一个原始指针。您需要的指针是unique_ptr
到同一节点。该指针存储在哪里?从tail
开始有一种简单的方法吗?
一旦有了unique_ptr
,就可以从列表中取消链接节点,就像resetting那个指针一样简单。请注意,无需手动调用release
和delete
节点。
现在pop_front
:在这里您已经拥有unique_ptr
,它是head
。但是您必须小心,因为整个列表都取决于此列表。重置head
将使整个列表消失。因此,请确保从head
分离列表的其余部分,然后首先将其与list
重新连接。如果您正确执行此操作,则删除原始head
甚至不会给您带来麻烦。试试吧!
请确保绘制列表的图片以可视化哪个节点指向何处。立即将所有这些信息保存在您的脑海中是很困难的。