A container is a collection of stored data, and a sequential container is used to specify its storage method as sequential storage. C ++ has three sequence containers: vector, deque, and list. The first two are sequential storage, and the third is the linked list. To separate algorithms from containers, STL provides few operations for these containers, such as insertion and deletion, and setting the container capacity, search and other operations are provided by the algorithm library.
In terms of efficiency, because the first two are sequential storage, they can support random access. If they are stored in a certain order, they can be more efficient in searching, but in inserting, the efficiency is not high because there is a move-back operation. List is the opposite. Therefore, in the selection of containers, we should select the appropriate and easy options based on the required business logic.
When talking about containers, you have to mention the iterator. Each container has its own iterator, which can be used to access elements inside the container. Its usage is similar to that of pointers. In fact, pointers can be considered as special iterators. Taking Vector as an example, the functions used to obtain the iterator are as follows:
[Cpp]
Vector: begin (3)
Return iterator to beginning (public member function)
Vector: end (3)
Return iterator to end (public member function)
Vector: rbegin (3) Return reverse iterator to reverse beginning (public member function)
Vector: rend (3) Return reverse iterator to reverse end (public member function)
[Html] view plaincopy
<Span style = "white-space: pre"> </span>
In other container methods, the iterator is also used in a large number. The specific reference document is better, so we will not detail it here.
For these three containers, they have many common functions, such as push_back, pop_back, insert, and erase, but some containers also have their own methods, for example, deque and list also have functions such as push_front and pop_front. The main difference lies in the implementation methods of these containers.
String can be seen as a special sequence container, which has almost all the basic functions of the container, so we can also access the string object through iteration.
Adapter
C ++ primer defines the adapter as follows:
A library type, function, or iterator that given a type, function, or iterator, makes it act like another. there are three sequential container adaptors: stack, queue, and priority_queue. each of these adaptors defines a new interface on top of an underlying sequential container.
I understand it in this way. An adapter is like an interface. It can encapsulate various containers at the underlying layer, and it shows an abstract type externally, this allows you to perform operations on the underlying container only through the interface functions provided by the abstract type.
Then, in my learning process, I gradually encountered a doubt. I read the C ++ help document, and the adapter generally only provides such a constructor, such as stack:
[Cpp]
Explicit stack (const Container & ctnr = Container ());
That is to say, if you do not provide a container for it, it will use its default container deque. If you provide a container for it, it will not maintain the container itself, but a copy of it.
A container adaptor keeps a container object as data. This container object is a copy of the argument passed to the constructor, if any, otherwise it is an empty container.
In this case, if I already hold a container, I will not be able to use the adapter to encapsulate the container, but can only encapsulate one copy of it, all operations performed through the interface are only valid for the copy, which seems to cause such a restriction: Only one adapter can be used to encapsulate the container, and after encapsulation, the original container should be discarded. This restriction makes it impossible to apply an adapter in the following scenarios: I hold a container and I want it to show different characteristics on different occasions, for example, in some scenarios, I want it to show only the characteristics of the stack, while in other scenarios, I want it to show the characteristics of the queue. The reason why the adapter cannot be used is the copy mechanism of the adapter. If I encapsulate the adapter using stacks and queues, the two queues will each get a copy of the original container, this results in data inconsistency, which makes it impossible for me to operate on the same container through different adapters.
In fact, there are similar concepts in java. The difference is that it can use interfaces to solve this problem. For example, a container can implement stack interfaces or queue interfaces, I can hold a stack reference variable and a queue reference variable, and let them all point to this container, then I can access the container through different references and only use the method unique to the reference. The problem is solved.
At the beginning of design, STL should not have taken this issue into consideration. Is there such a mechanism that can solve this problem? If any of you are passing by, please leave your pen and ink to answer your questions. I am very grateful to you.
Author: justaipanda