gpt4 book ai didi

c++ - 使用 unique_ptrs 的基本前向列表

转载 作者:行者123 更新时间:2023-12-02 18:12:57 27 4
gpt4 key购买 nike

作为学习 C++ 的练习,我想使用原始指针和 unique_ptrs 构建自己的前向列表。使用原始指针,我有:

struct node_raw {
node_raw(int data_, node_raw *next_) : data(data_), next(next_) {}
int data;
node_raw *next;
};

那我就可以写这个了

int main() {
node_raw r1{1, nullptr};
node_raw r2{2, &r1};
node_raw r3{3, &r2};
}

获取转发列表:r3 -> r2 -> r1。

现在我想使用 unique_ptrs 执行相同的操作。

struct node_unique {
node_unique(int data_, std::unique_ptr<node_unique> next_)
: data(data_), next(std::move(next_)) {}
int data;
std::unique_ptr<node_unique> next;
};

这是我到目前为止的客户端代码:

int main() {
node_unique u1{1, nullptr};
node_unique u2{2, std::make_unique<node_unique>(std::move(u1))};
node_unique u3{3, std::make_unique<node_unique>(std::move(u2))};
}

这给出了u3.next->data = 2,所以它似乎有效。但这是对的吗?为什么我需要 std::move 两次才能创建新节点?现在查询 u1.data 是否无效,因为它已被移出?基本上,使用 unique_ptrs 实现最小前向列表的规范方法是什么?

最佳答案

Why do I need std::move twice to make a new node?

您无法复制 node_unique,因为它因 std::unique_ptr 成员而隐式删除了复制构造函数。

Is it now invalid to query u1.data because it has been moved from?

没有。隐式生成的 move 构造函数将复制该成员。读取从中复制的 int 成员并非无效。

But is it right?

节点类本身并没有什么大问题1,但您使用它的方式可能会产生误导。 u1u2 不属于根为 u3 的列表。列表节点是移出的 u1u2 的浅表拷贝。

您不一定需要这些变量;由于列表元素是动态的,您可以直接创建它们:

node_unique root (
3,
std::make_unique<node_unique>(
2,
std::make_unique<node_unique>(
1,
nullptr
)
)
);

Basically, what is the canonical way to implement a minimal forward list using unique_ptrs?

“最小”与您的要求相关。您可以通过删除构造函数使节点变得更小 aggregate .

我不会说有一种“规范”的方法来实现转发列表,但预计它会满足容器的概念。然而,这并不是最小的。


1 除了析构函数具有线性递归深度这一事实之外,这将导致中等大小列表的堆栈溢出,如 Remy Lebeau 所指出的.

您应该实现一个自定义析构函数来迭代地销毁节点。这需要一些思考来防止智能指针析构函数深入递归。

关于c++ - 使用 unique_ptrs 的基本前向列表,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/72030976/

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