简体   繁体   English

STL List和Vector是如何实现的?

[英]How are STL List and Vector implemented?

How are STL List and Vector implement? STL List和Vector如何实现?

I was just asked this in an an interview. 我在接受采访时被问到这个问题。

I just said maybe by using binary tree or hash table about vector. 我刚才说可能是通过使用关于向量的二叉树或哈希表。 not sure about list... Am I wrong, I guess so.. give some ideas thanks. 不确定列表...我错了,我想是的......给一些想法谢谢。

Hash table or binary tree? 哈希表还是二叉树? Why? 为什么?

std::vector , as the name itself suggests, is implemented with a normal dynamically-allocated array, that is reallocated when its capacity is exhausted (usually doubling its size or something like that). 正如名称本身所暗示的那样, std::vector是用一个正常的动态分配数组实现的,当它的容量耗尽时(通常是它的大小加倍或类似的东西)重新分配。

std::list instead is (usually 1 ) implemented with a doubly-linked list. std::list代替(通常是1 )用双向链表实现。

The binary tree you mentioned is the usual implementation of std::map ; 你提到的二叉树是std::map的通常实现; the hash table instead is generally used for the unordered_map container (available in the upcoming C++0x standard). 相反,散列表通常用于unordered_map容器(在即将推出的C ++ 0x标准中可用)。


  1. "Usually" because the standard do not mandate a particular implementation, but specifies the asymptotic complexity of its methods, and such constraints are met easily with a doubly-linked list. “通常”因为标准不强制要求特定的实现,而是指定其方法的渐近复杂性,并且使用双向链表很容易满足这些约束。 On the other hand, for std::vector the "contiguous space" requirement is enforced by the standard (from C++03 onwards), so it must be some form of dynamically allocated array. 另一方面,对于std::vector ,“连续空间”要求由标准强制执行(从C ++ 03开始),因此它必须是某种形式的动态分配数组。

std::vector uses a contiguously allocated array and placement new std::vector使用连续分配的数组和placement new

std::list uses dynamically allocated chunks with pointer to the next and previous element. std::list使用动态分配的块,其中包含指向下一个和上一个元素的指针。

nothing as fancy as binary trees or hash tables (which can be used for std::map ) 没有像二进制树或哈希表那样花哨(可以用于std::map

You can spend half a semester talking about either of the containers, but here are a few points: 你可以花半个学期谈论任何一个容器,但这里有几点:

std::vector is a contiguous container, which means every element follows right after the previous element in memory. std::vector是一个连续的容器,这意味着每个元素都紧跟在内存中的前一个元素之后。 It can grow at runtime, which means it allocates its storage in dynamic memory. 它可以在运行时增长,这意味着它在动态内存中分配其存储。

std::list is a bidirectional linked list. std::list是一个双向链表。 This means that the elements are scattered in memory in arbitrary layout, and that each element knows where the next and previous elements in sequence are. 这意味着元素以任意布局分散在内存中,并且每个元素都知道序列中下一个和前一个元素的位置。

std::vector , std::list and the other containers don't take ownership of the elements they hold, but they do cleanup after themselves. std::vectorstd::list和其他容器不会获取它们所持有的元素的所有权,但它们会自行清理。 So, if the elements are pointers to dynamic memory then the user must free the pointers before the container destructs. 因此,如果元素是指向动态内存的指针,那么用户必须在容器破坏之前释放指针。 But if the container contains automatic data then the data's destructors will call automatically upon the container's cleanup. 但是如果容器包含自动数据,那么数据的析构函数将在容器清理时自动调用。

So far, very simple and roughly equivalent to any other language or toolset. 到目前为止,非常简单,大致相当于任何其他语言或工具集。 What's unique about the STL is that the containers are generic and decoupled from the means of iterating over them and (for the most part) from the operations you can perform over them. STL的独特之处在于,容器是通用的,并且与迭代它们的方式(大多数情况下)从您可以对它们执行的操作分离。 Some operations can be done particularly efficiently with some containers, so the containers will provide member functions in these cases. 某些操作可以使用某些容器特别有效地完成,因此容器将在这些情况下提供成员功能。 For example, std::list has a sort() member function. 例如, std::list有一个sort()成员函数。

The STL doesn't provide container classes (for the most part), but rather container templates . STL不提供容器 (大多数情况下),而是提供容器模板 In other words, when the library talks about a container it only refers to the data type anonymously, say, as T , never by its true name. 换句话说,当库谈论一个容器时,它只是匿名地引用数据类型,比如T ,而不是它的真实名称。 Never int or double or Car ; 绝不是intdoubleCar ; always T , for any type. 对于任何类型,总是T There are exceptions, like std::vector<bool> , but this is the general case. 有一些例外,比如std::vector<bool> ,但这是一般情况。 Then, when the user instantiates a container template, they specify a type, and the compiler creates a container class from the template for that type. 然后,当用户实例化容器模板时,它们指定一个类型,并且编译器从该类型的模板创建容器类。

The STL also offers algorithms as free template functions. STL还提供算法作为免费模板功能。 These algorithms work on iterators , themselves templates. 这些算法适用于迭代器本身的模板。 Often iterators come in pairs that denote the beginning and end of a sequence, on which the algorithm operates. 通常,迭代器成对出现,表示算法运行的序列的开始和结束。 std::vector , std::list and other containers then expose their own iterators that can traverse and manipulate their data. std::vectorstd::list和其他容器然后公开他们自己的迭代器,它可以遍历和操纵他们的数据。 So the same free algorithm can work on a std::vector and a std::list and other containers, provided the iterators conform with specific assumptions about the iterators' abilities. 因此,相同的自由算法可以在std::vectorstd::list以及其他容器上工作,前提是迭代器符合有关迭代器能力的特定假设。

All this abstraction is done at compile-time, and that is the biggest difference when compared to other languages. 所有这些抽象都是在编译时完成的,与其他语言相比,这是最大的区别。 This translates to outstanding performance with relatively short and concise code. 这可以通过相对简短的代码转换为出色的性能。 The same performance that in C you'd only get with lots of copy-pasting or hardcoding. 与C相同的性能,您只能通过大量复制粘贴或硬编码获得。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM