对<type>链表使用列表和指针(经典 C)之间的差异
diffrence between using list<type> and pointers (classic C) for linked lists
使用内置的std::list
而不是像C那样基于指针的自己的链表实现的优点/缺点是什么?
是否存在一些特殊情况,其中一个优于另一个?
使用std::list
而不是自己的链表实现有很多很好的理由:
-
std::list
是有保证的(通过c++标准库的执行标准)按照锡板上的说明工作(编号 -
std::list
不需要您花时间开发和测试。 -
std::list
是众所周知的,所以任何人都可以与之合作代码(或者你以后的生活)可以理解发生了什么不需要首先掌握自定义链表实现。
我真的想不出任何好的理由来使用你自己的自定义链表。
std::list
通常实现为双链表。如果你只需要一个单链表,你应该考虑std::forward_list
。
最后,如果你关心性能,你根本不应该使用链表。链表中的元素必须单独分配(并且通常插入在随机位置),因此处理链表通常会导致许多缓存丢失,每次都会造成性能损失。
通常,您希望使用std::list
,如@Walter所回答的。
然而,通过"侵入式"将next(和prev,如果有的话)指针直接集成到所包含的对象中来实现的列表,可以避免std::list
和其他STL容器的几个缺点,这些缺点可能与您相关,也可能与您无关(引用自Boost)。侵入性的文档):
- 一个对象只能属于一个容器:如果你想共享一个对象在两个容器之间,您必须存储它们的多个副本对象,或者需要使用指针容器:
std::list<Object*>
.- 使用动态分配来创建传递值的副本可以是一个某些应用程序的性能和大小瓶颈。[…]
- 只有对象的副本存储在非侵入性容器中。因此复制或移动构造函数和复制或移动赋值操作符是必需的。不可复制和不可移动的对象不能存储在非侵入性中容器。
在stl容器中存储派生对象是不可能的
第二点可能不适用于大多数典型的列表用法,在这些用法中,无论如何都要动态分配元素。
如果最后一点与您相关,那么您可能对Boost感兴趣。指针容器——尽管std::list<std::unique_ptr<Obj>>
通常也能很好地完成这项工作。
与其自己完全实现一个列表,不如看看前面提到的Boost。侵入性的图书馆。
Walter提供的答案涵盖了首选stl实现的主要原因。考虑经典C风格实现的主要原因是提高性能。这种性能提高的代价主要是潜在的错误。这可以通过测试和包含一些适当的断言(检查空指针…_
)来解决。与Walter回答中的陈述相反,在某些情况下,高性能列表是一个很好的数据结构选择。
如果你需要自定义列表的性能,但又想避免构建和测试自己的列表,请查看boost侵入列表(单链接和双链接):http://www.boost.org/doc/libs/1_39_0/doc/html/intrusive.html这将使您获得与自定义构造相同的性能,并且(几乎)具有stl版本的便利性。
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- QMetaObject invokeMethod的基于函数指针的语法
- 如何从 std::atomic 中提取指针 T<T>?
- 如何在 C# 中映射双 C 结构指针?
- C++将浮点指针值舍入为小数位数
- 为什么++(*p)更改指针值
- 调整大小后指向元素值的指针unordered_map有效?
- 正在将指针转换为范围
- 使用指向成员的指针将成员函数作为参数传递
- 对<type>链表使用列表和指针(经典 C)之间的差异
- c++中使用指针的经典对象列表