C + + Abstract container type I (vector, list)

Keywords: C++ Container

1, Container

When you first understand containers, you can think of containers as libraries that provide a series of specific functions.

2, Common containers

STL Classification of standard template library:

    Sequence container:
            vector: Vector container
            list  : List container
            deque : Dual ended queue container
    
    Associated container: query whether an element exists and effectively obtain the element data.
            map(mapping)
            set(aggregate)
    
    Hash container:
            unordered_set      Hash set
            unordered_multiset Hash multiple set
            unordered_map      Hash Map 
            unordered_multimap Hash multiple mapping        

3, On the self growth characteristics of vector container

When we define a vector object to output its length and capacity, we find that it is: 0, 0;
When we add more than a certain number of elements, we output its capacity and find that the capacity becomes larger. This reflects the self growth of vector. (use size and capacity to get length and capacity)
Specific examples are as follows:

#include <vector>
#include <iostream>
using namespace std;

int main()
{
    //Define a vector object
    vector< int > ivec;

    //The length and size of the output element vector object before adding a new element to the output
    cout << "ivec: size: " << ivec.size()
    << " capacity: " << ivec.capacity() << endl;
    
    //Add multiple elements to the container object to see the length and capacity
    for ( int ix = 0; ix < 24; ++ix ) {
    ivec.push_back( ix );
    cout << "ivec: size: " << ivec.size()
    << " capacity: " << ivec.capacity() << endl;
    }
}

Operation results:

ivec: size: 0 capacity: 0
ivec: size: 1 capacity: 1
ivec: size: 2 capacity: 2
ivec: size: 3 capacity: 4
ivec: size: 4 capacity: 4
ivec: size: 5 capacity: 8
ivec: size: 6 capacity: 8
ivec: size: 7 capacity: 8
ivec: size: 8 capacity: 8
ivec: size: 9 capacity: 16
ivec: size: 10 capacity: 16
ivec: size: 11 capacity: 16
ivec: size: 12 capacity: 16
ivec: size: 13 capacity: 16
ivec: size: 14 capacity: 16
ivec: size: 15 capacity: 16
ivec: size: 16 capacity: 16
ivec: size: 17 capacity: 32
ivec: size: 18 capacity: 32
ivec: size: 19 capacity: 32
ivec: size: 20 capacity: 32
ivec: size: 21 capacity: 32
ivec: size: 22 capacity: 32
ivec: size: 23 capacity: 32
ivec: size: 24 capacity: 32

The above shows that the capacity grows by 8 bytes, and the specific growth characteristics are determined by the platform!

When using vector, every time you apply to free memory, the application needs to call the copy constructor for each element, and the destructor for each element.
If the dynamic self growth of the vector is frequent, the greater the cost of inserting elements.

resolvent:

① When vector costs a lot, it can be replaced with a list container
② Objects of complex classes are stored indirectly through pointers. The copy and release of the pointer to the class do not need to call the copy constructor and destructor of the class!

3, Basic use of sequential container vector in list

① Basic ways to define container objects

1) Define object uncertainty capacity
2) Define objects and determine capacity
3) Define the object and determine the length, and initialize it at the same time

② To define objects and uncertain capacity, we can directly define the objects of vector container and list container. As follows: if the length of the object is not determined, the length is 0, that is, empty.

	#include <iostream>
	#include <vector>
	#include <list>
	#include <string>
	using namespace std;
	
	int main()
	{
	    //Defines a shaping vector container object
	    vector <int> i_vec;
	
	    //Defines a string list container object
	    list <string> s_lis;
	
	    //No length was determined. The output length is 0
	    cout<<"i_vec Length of:"<<i_vec.size()<<endl;
	    cout<<"is_lis Length of:"<<s_lis.size()<<endl;
	
	    //If the length is not determined, it is empty
	    if(i_vec.empty() && s_lis.empty())
	    {
	        cout<<"Both objects are empty!"<<endl;
	    }
	    return 0;
	}

Operation results:

i_ Length of VEC: 0
is_ Length of LIS: 0
Both objects are empty!

③ Determine the object capacity. The following example determines that the length of the object is 10, so it is not empty!

#include <iostream>
#include <vector>
#include <list>
#include <string>
using namespace std;

int main()
{
    //Define a shaping vector container object and determine the length as 10
    vector <int> i_vec(10);
    //Define a string list container object with a length of 10
    list <string> s_lis(10);

    //No length was determined. The output length is 0
    cout<<"i_vec Length of:"<<i_vec.size()<<endl;
    cout<<"is_lis Length of:"<<s_lis.size()<<endl;
    
    //If the length is not determined, it is empty
    if(!(i_vec.empty()) && !(s_lis.empty()))
    {
        cout<<"Neither object is empty!"<<endl;
    }
    return 0;
}

④ Determine the capacity and initialize the container object

#include <iostream>
#include <vector>
#include <list>
#include <string>
using namespace std;

int main()
{
    //Define an integer vector container object, determine the length of 10, and initialize to - 1
    vector <int> i_vec(10,-1);

    //Define a string list container object, determine the length of 10, and initialize it to "dante"
    list <string> s_lis(10,"dante");

    //No length was determined. The output length is 0
    cout<<"i_vec Length of:"<<i_vec.size()<<endl;
    cout<<"is_lis Length of:"<<s_lis.size()<<endl;

    //If the length is not determined, it is empty
    if(!(i_vec.empty()) && !(s_lis.empty()))
    {
        cout<<"Neither object is empty!"<<endl;
    }

    for(int n=0; n<i_vec.size(); n++)
    {
        cout<<"i_vec["<<n<<"] = "<<i_vec[n]<<endl;
    }
    list <string> ::iterator mp;
    for(mp = s_lis.begin(); mp != s_lis.end(); mp++)
    {
        cout<<"s_lis:"<<*mp<<endl;
    }
    return 0;
}

Operation results:

i_ Length of VEC: 10
is_ Length of LIS: 10
Both objects are not empty!
i_vec[0] = -1
i_vec[1] = -1
i_vec[2] = -1
i_vec[3] = -1
i_vec[4] = -1
i_vec[5] = -1
i_vec[6] = -1
i_vec[7] = -1
i_vec[8] = -1
i_vec[9] = -1
s_lis:dante
s_lis:dante
s_lis:dante
s_lis:dante
s_lis:dante
s_lis:dante
s_lis:dante
s_lis:dante
s_lis:dante
s_lis:dante

⑤ About container capacity and size

Container capacity: the maximum number of elements that can be stored
Container size: the number of elements in the current container
Expansion of container capacity: resize – when the set capacity is smaller than the current capacity, the capacity remains unchanged.

⑥ Comparison size of container object

The comparison of equal to not equal to less than or equal to and greater than or equal to containers means that the elements of two containers are compared in pairs. If all elements are equal and the two containers contain the same number of elements, the two containers are equal. Otherwise, they are not equal. The comparison of the first unequal element determines the less than or greater relationship between the two containers.
Similar to string sizing logic.

Posted by herschen on Thu, 11 Nov 2021 10:27:33 -0800