使用智能指针的 C++ 链表
我只对带有模板的链表使用原始指针.例如,成员数据,Node
,当我插入一个节点时,其中一行是 head = new Node
代码>.
I have only been using raw pointers for linked list with templates. For example, the member data, Node<T>* head;
and when I am inserting a node one of the lines would be head = new Node<T>(data);
.
但是,现在我需要使用智能指针,但我不确定如何将其更改为使用智能指针.是否将成员数据更改为shared_ptr
和另一行将更改为head = shared_ptr
?
However, now I need to use a smart pointer and I am not sure how I would change it to use smart pointers. Would the member data be changed to shared_ptr<Node<T>> head;
and the other line would change to
head = shared_ptr<Node<T>>( new <Node<T>>(data) );
?
推荐答案
对于链表,您并不需要"使用智能指针,因为该声明没有意义.您不要将智能指针用于低级数据结构.您将智能指针用于高级程序逻辑.
You do not "need" to use a smart pointer for a linked list, because that statement doesn't make sense. You do not use smart pointers for low-level data structures. You use smart pointers for high-level program logic.
就低级数据结构而言,您使用来自 C++ 标准库的标准容器类,例如 std::list
[*],它无论如何都可以解决您所有的内存管理问题,而无需在内部使用任何智能指针.
As far as low-level data structures are concerned, you use a standard container class from the C++ standard library, like std::list
[*], which solves all your memory-management problems anyway, without using any smart pointers internally.
如果您真的需要自己的高度专业化/优化的自定义容器类,因为整个 C++ 标准库不适合您的要求,并且您需要替换std::list
、std::vector
、std::unordered_map
和其他优化、测试、记录和安全的容器我非常怀疑!–,那么无论如何你都必须手动管理内存,因为这样一个专门类的重点几乎肯定是需要诸如内存池、写时复制甚至垃圾收集之类的技术,所有这些都与典型的智能指针相当简单的删除逻辑.
If you really really need your own highly specialised/optimised custom container class because the entire C++ standard library is unfit for your requirements and you need a replacement for std::list
, std::vector
, std::unordered_map
and other optimised, tested, documented and safe containers – which I very much doubt! –, then you have to manage memory manually anyway, because the point of such a specialised class will almost certainly be the need for techniques like memory pools, copy-on-write or even garbage collection, all of which conflict with a typical smart pointer's rather simplistic deletion logic.
用Herb Sutter 的话来说:
永远不要使用拥有原始指针和删除,除非在极少数情况下实现你自己的低级数据结构(即使这样保持很好地封装在类边界内).
Never use owning raw pointers and delete, except in rare cases when implementing your own low-level data structure (and even then keep that well encapsulated inside a class boundary).
Herb Sutter 和 Bjarne Stroustrup 的 C++ 核心指南:
这个问题不能通过转换所有所有权来解决(大规模)指向 unique_ptrs 和 shared_ptrs 的指针,部分是因为 我们需要/使用在实现中拥有原始指针"和简单指针我们的基本资源句柄.例如,公共向量实现有一个拥有指针和两个非拥有指针.
This problem cannot be solved (at scale) by transforming all owning pointers to unique_ptrs and shared_ptrs, partly because we need/use owning "raw pointers" as well as simple pointers in the implementation of our fundamental resource handles. For example, common vector implementations have one owning pointer and two non-owning pointers.
使用原始指针在 C++ 中编写链表类可能是一项有用的学术练习.使用智能指针用 C++ 编写链表类是毫无意义的学术练习.在生产代码中使用这两种自制的东西中的任何一种几乎都是错误的.
Writing a linked-list class in C++ with raw pointers can be a useful academic exercise. Writing a linked-list class in C++ with smart pointers is a pointless academic exercise. Using any of these two self-made things in production code is almost automatically wrong.
[*] 或者只是std::vector
,因为由于缓存局部性,无论如何它几乎总是更好的选择.
[*] Or just std::vector
, because due to cache locality that will almost always be the better choice anyway.
相关文章