Visual C++ 6 Unleashed

Visual C++ 6 Unleashed

By MICKEY WILLIAMS and David Bennett

Containers

A container is a data structure that manages a collection of elements. The container itself is responsible for the allocation and deallocation of its elements, as well as methods for adding and deleting elements. Containers most typically contain constructors and destructors as well.

The containers supplied in the STL consist of two categories: sequence and associative. Sequence containers store elements in sequential order, like a C++ array (which is, in fact, a container). Sequence containers are List, Deque, and Vector. Associative containers are not sequential and use keys to access data. The keys usually are strings or numeric. The associative containers consist of Map, Multimap, Multiset, and Set.

Sequence Containers

Sequence containers store elements in sequential order. It is a linear arrangement where every element in the container is related to the other elements by its position. The containers Vector, List, and Deque are sequence containers.

The Vector Container

The Vector container takes care of the shortcomings of the C++ array. Unlike the C++ array, the vector is an expandable array: It doesn't have to specify its size at compile time. It is very fast and efficient at inserting and removing elements at the end of the array and is quick at random access, but it is slow at inserting or deleting elements from the middle. Table 13.1 lists the member functions and type definitions of the Vector container.

Table 13.1. The Vector Container: Member Functions and Type Definitions

Function Definition
allocator_type Type definition for template.
assign Assignment function for sequences.
at Returns a reference to the element of the controlled sequence.
back Returns a reference to the last element of the controlled sequence. The last element must be non-empty.
begin Returns a random-access iterator that points to the first element of the sequence.
capacity Returns a value equal to the storage currently allocated to hold the controlled sequence. This value will be at least as large as size().
clear Calls erase(), begin(), and end().
const_iterator Type definition for constant random-access iterator for the sequence.
const_reference Type definition for a constant reference to an element for the sequence.
const_reverse_iterator Type definition for a constant reverse iterator for the sequence.
difference_type Signed integer type defines an object that can represent the difference between the addresses of any two elements of the sequence.
empty Returns True for an empty sequence.
end Returns a random-access iterator that points just beyond the end of the sequence.
erase Function that can remove the element of the sequence pointed to by it or remove a range of elements.
front Returns the first element of a sequence. The first element must be non-empty.
get_allocator Returns allocator.
insert Inserts an element, a repetition of elements, or the sequence. When inserting a single element, the iterator of the element is returned.
iterator Type definition that can serve as a random-access iterator for the sequence.
max_size Returns the length of the largest sequence the object can use.
operator[] Returns a reference to the element of the sequence at the declared position.
pop_back Removes the last element of the sequence. The last value must be empty.
push_back Inserts an element at the end of the sequence.
rbegin Returns a reverse iterator that points just beyond the end of the sequence.
reference Type definition for an object that can be a reference to an element of the sequence.
rend Returns a reverse iterator that points to the first element of the sequence.
reserve Ensures the storage currently allocated to hold the controlled sequence. The size of the storage is returned.
resize Ensures the storage currently allocated to hold the controlled sequence. If the size of the sequence must be increased, it adds the number of elements specified.
reverse_iterator Type definition that can serve as a reverse iterator for the sequence.
size Returns the length of the sequence.
size_type Type definition that describes an object that can represent the length of a sequence.
swap Swaps two sequences.
value_type Type definition for value_type.
vector Constructor for the vector template class. It can specify an empty sequence, a repetition of elements, or a copy of another sequence.

A code example of the common Vector functions follows. The functions represented in this code are back, empty, erase, pop_back, push_back, Operator[], size, and swap.

Example 13.1. Common Vector Operations

//Common Vector Operations
//
// Member Functions: push_back, pop_back, size, Operator[]
//                    swap, empty, back, insert, erase

#include <iostream>
#include <vector>

using namespace std ;

typedef vector<int> INTVECTOR;

//Main
void main(){

INTVECTOR VectorSet1;        //Declare 4 vectors of integer
INTVECTOR VectorSet2(3) ;

// Iterator is used to loop through the vector.
INTVECTOR::iterator MyIterator;

//Insert Elements using push_back
VectorSet1.push_back(1);
VectorSet1.push_back(2);
VectorSet1.push_back(3);

//Insert Elements using Operator[]
VectorSet2[0] = 10;
VectorSet2[1] = 11;
VectorSet2[2] = 12;

//Print Vector Size
cout << "The Size of VectorSet1 is: " << VectorSet1.size() << endl << endl;

// print VectorsSet1 contents
cout << "Contents of VectorSet1:" << endl;
   for(MyIterator = VectorSet1.begin();
    MyIterator != VectorSet1.end();
    MyIterator++)
   cout << *MyIterator << endl;
cout << endl;

// print VectorsSet2 contents
cout << "Contents of VectorSet2:" << endl;
    for(MyIterator = VectorSet2.begin();
    MyIterator != VectorSet2.end();
    MyIterator++)
cout << *MyIterator << endl;
cout << endl;

//Swap VectorSet1 with VectorSet2
VectorSet1.swap(VectorSet2);

// print VectorsSet1 contents
cout << "Contents of VectorSet1 after Swap:" << endl;
   for(MyIterator = VectorSet1.begin();
    MyIterator != VectorSet1.end();
    MyIterator++)
cout << *MyIterator << endl;
cout << endl;

// print last element in VectorSet1
cout << "Last element in VectorSet1: " << VectorSet1.back() << endl;

//Empty out vector1
while( !VectorSet1.empty() )
{
cout << "Popping element " << VectorSet1.back() << endl;
VectorSet1.pop_back();
}
cout << endl;

cout << "Contents of VectorSet1:" << endl;
    for(MyIterator = VectorSet1.begin();
    MyIterator != VectorSet1.end();
    MyIterator++)
    cout << *MyIterator << endl;
cout << endl;

//Insert number 44
VectorSet2.insert(VectorSet2.begin() + 1, 44);
// print VectorsSet2 contents after insert
   cout << "Contents of VectorSet2 after insert:" << endl;
   for(MyIterator = VectorSet2.begin();
   MyIterator != VectorSet2.end();
   MyIterator++)
cout << *MyIterator << endl;
cout << endl;

//Erase number 44
  VectorSet2.erase(VectorSet2.begin() + 1);
// print VectorsSet2 contents after erase
cout << "Contents of VectorSet2 after erase:" << endl;
    for(MyIterator = VectorSet2.begin();
    MyIterator != VectorSet2.end();
    MyIterator++)
cout << *MyIterator << endl;
cout << endl;
} //END

The output of this code follows:

The Size of VectorSet1 is: 3

Contents of VectorSet1:
1
2
3

Contents of VectorSet2:
10
11
12

Contents of VectorSet1 after Swap:
10
11
12

Last element in VectorSet1: 12
Popping element 12
Popping element 11
Popping element 10
Contents of VectorSet1:

Contents of VectorSet2 after insert:
1
44
2
3

Contents of VectorSet2 after erase:
1
2
3
							

The List Container

The List container allows the quick addition and removal of elements anywhere in the list. This is kind of like the linked-list version of the Vector container. Though quick to access either end, it is slow at random access. Table 13.2 lists the member functions and type definitions of the List container.

Table 13.2. The List Container: Member Functions and Type Definitions

Function Description
allocator_type Type definition for template.
assign Assignment function for sequences.
at Returns a reference to the element of the controlled sequence.
back Returns a reference to the last element of the controlled sequence. The last element must be non-empty.
begin Returns a random-access iterator that points to the first element of the sequence.
clear Calls erase(), begin(), and end().
const_iterator Type definition for constant random-access iterator for the sequence.
const_reference Type definition for a constant reference to an element for the sequence.
const_reverse_iterator Type definition for a constant reverse iterator for the sequence.
difference_type Signed integer type defines an object that can represent the difference between the addresses of any two elements of the sequence.
empty Returns True for an empty sequence.
end Returns a random-access iterator that points just beyond the end of the sequence.
erase Function that can remove the element of the sequence pointed to by it or remove a range of elements.
front Returns the first element of a sequence. The first element must be non-empty.
get_allocator Returns allocator.
insert Inserts an element, a repetition of elements, or the sequence. When inserting a single element, the iterator of the element is returned.
iterator Type definition that can serve as a random-access iterator for the sequence.
list Constructor for the list template class. It can specify an empty sequence, a repetition of elements, or a copy of another sequence.
max_size Returns the length of the largest sequence that the object can use.
merge Merges two sequences.
operator[] Returns a reference to the element of the sequence at the declared position.
pop_back Removes the last element of the sequence. The last value must be empty.
pop_front Removes the first element of the sequence. The first value must be non-empty.
push_back Inserts an element at the end of the sequence.
push_front Removes an element from the front of the sequence.
rbegin Returns a reverse iterator that points just beyond the end of the sequence.
reference Type definition for an object that can be a reference to an element of the sequence.
remove Removes elements from the sequence.
remove_if Removes elements from the sequence based on a condition.
rend Returns a reverse iterator that points to the first element of the sequence.
resize Ensures the storage currently allocated to hold the controlled sequence. If the size of the sequence must be increased, it adds the number of elements specified.
reverse Reverses the order of the elements in a sequence.
reverse_iterator Type definition that can serve as a reverse iterator for the sequence.
size Returns the length of the sequence.
size_type Type definition that describes an object that can represent the length of a sequence.
sort Orders the elements of the sequence by a determined predicate.
splice Performs splice operations on the elements in the sequence.
swap Swaps two sequences.
value_type Type definition for value_type.
unique Removes duplicate elements that equal the desired value.

The following example demonstrates three functions that are unique to List: merge(), reverse(), and unique().

Example 13.2. Common Vector Operations 2

//Common Vector Operations
//
// Member Functions: merge, reverse, and unique

#include <iostream>
#include <list>
#include <string>

using namespace std ;

typedef list<string> LISTSTR;

//Main
void main(){

LISTSTR List1;
LISTSTR List2;

LISTSTR::iterator MyIterator;
List1.push_back("1");
List1.push_back("2");
List1.push_back("3");

List2.push_back("3");
List2.push_back("4");
List2.push_back("5");

// print VectorsSet1 contents
cout << "Contents of List1:" << endl;
    for(MyIterator = List1.begin();
    MyIterator != List1.end();
    MyIterator++)
cout << *MyIterator << endl;
cout << endl;

//Merge Both lists
List1.merge(List2);

// print VectorsSet1 contents
cout << "Contents of List1 after merge:" << endl;
    for(MyIterator = List1.begin();
    MyIterator != List1.end();
MyIterator++)
       cout << *MyIterator << endl;
cout << endl;

//Reverse List1
    List1.reverse();

// print VectorsSet1 contents
cout << "Contents of List1 after reverse:" << endl;
    for(MyIterator = List1.begin();
    MyIterator != List1.end();
MyIterator++)
       cout << *MyIterator << endl;
cout << endl;

//remove duplicates List1
    List1.unique();

// print VectorsSet1 contents
cout << "Contents of List1 after unique:" << endl;
    for(MyIterator = List1.begin();
    MyIterator != List1.end();
MyIterator++)
   cout << *MyIterator << endl;
cout << endl;
} //END

Unless you specify -GX when compiling, you will receive numerous warnings upon compiling the program. The results of this program are pretty obvious, as shown here:

Contents of List1:
1
2
3

Contents of List1 after merge:
1
2
3
3
4
5

Contents of List after reverse:
5
4
3
3
2
1

Contents of List1 after unique:
5
4
3
2
1
							

The Deque Container

The third sequence container is the Deque (double-ended queue). The Deque is actually like a stack and queue combined. Like a stack, all the input and output takes place at the top of the stack (LIFO). In a queue, all data goes in the front and comes out the back (FIFO). With the Deque container, these attributes are combined so that elements can be inserted or deleted at either end. This makes it quite flexible and thus is used as the basis for stacks and queues. Table 13.3 lists the member functions and type definitions of the Deque container.

Table 13.3. The Deque Container: Member Functions and Type Definitions

Function Description
allocator_type Type definition for template.
assign Assignment function for sequences.
at Returns a reference to the element of the controlled sequence.
back Returns a reference to the last element of the controlled sequence. The last element must be non-empty.
begin Returns a random-access iterator that points to the first element of the sequence.
clear Calls erase(), begin(), and end().
const_iterator Type definition for constant random-access iterator for the sequence.
const_reference Type definition for a constant reference to an element for the sequence.
const_reverse_iterator Type definition for a constant reverse iterator for the sequence.
difference_type Signed integer type defines an object that can represent the difference between the addresses of any two elements of the sequence.
empty Returns True for an empty sequence.
end Returns a random-access iterator that points just beyond the end of the sequence.
erase Function that can remove the element of the sequence pointed to by it or remove a range of elements.
front Returns the first element of a sequence. The first element must be non-empty.
get_allocator Returns allocator.
insert Inserts an element, a repetition of elements, or the sequence. When inserting a single element, the iterator of the element is returned.
iterator Type definition that can serve as a random-access iterator for the sequence.
list Constructor for the list template class. It can specify an empty sequence, a repetition of elements, or a copy of another sequence.
max_size Returns the length of the largest sequence the object can use.
merge Merges two sequences.
operator[] Used to reference elements directly.
pop_back Removes the last element of the sequence. The last value must be empty.
pop_front Removes the first element of the sequence. The first value must be non-empty.
push_back Inserts an element at the end of the sequence.
push_front Inserts an element at the beginning of the sequence.
rbegin Returns a reverse iterator that points just beyond the end of the sequence.
reference Type definition for an object that can be a reference to an element of the sequence.
rend Returns a reverse iterator that points to the first element of the sequence.
resize Ensures the storage currently allocated to hold the controlled sequence. If the size of the sequence must be increased, it adds the number of elements specified.
reverse Reverses the order of the elements in a sequence.
reverse_iterator Type definition that can serve as a reverse iterator for the sequence.
size Returns the length of the sequence.
size_type Type definition that describes an object that can represent the length of a sequence.
swap Swaps two sequences.
value_type Type definition for value_type.

An example of a Deque container, supporting push_front, pop_front, and front(), follows:

Example 13.3. Deque Example

//Deque example
//
// Member Functions: push_back, push_front
//

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

typedef deque<int> INTDEQUE;

//Main
void main(){

INTDEQUE::iterator MyIterator;
INTDEQUE  deque1;

deque1.push_back(2);
deque1.push_front(1);
deque1.push_back(3);


// print deque contents
cout << "Contents of deque1:" << endl;
for(MyIterator = deque1.begin();
    MyIterator != deque1.end();
    MyIterator++)
cout << *MyIterator << endl;
cout << endl;

} //END

Unless you specify -GX when compiling, you will receive numerous warnings upon compiling the program. The results of this program are pretty obvious, as shown here:

Contents of deque1:
1
2
3

Note the manner of how the elements were placed in the Deque and the final results.

Associative Containers

Associative containers use keys to access data and are not sequential. The keys typically are numeric or strings. The keys are used automatically by the container to arrange the stored elements in a specific order.

There are two types of associative containers in the STL: sets and maps. A set only stores the key without the associated values. A map associates a key with a value. This value can be any type of object.

Both types of containers only allow one key per given value. It is a one-to-one relationship. However, if the need arises for multiple keys per value, the Multiset and Multimap containers are the ones to use.

Table 13.4 lists the member functions and type definitions of Map, Multimap, Set, and Multiset containers. All apply except for the respective constructors and those otherwise noted.

Table 13.4. Map, Multimap, Set, and Multiset Containers: Member Functions and Type Definitions

Function Description
allocator_type Type definition for template.
begin Returns a bidirectional iterator that points to the first element of the sequence.
clear Calls erase(), begin(), and end().
const_iterator Type definition for a constant bidirectional iterator for the sequence.
const_reference Type definition for a constant reference to an element for the sequence.
const_reverse_iterator Type definition for a constant reverse bidirectional iterator for the sequence.
count Returns the number of elements of a given range.
difference_type Signed integer type defines an object that can represent the difference between the addresses of any two elements of the sequence.
empty Returns True for an empty sequence.
end Returns a bidirectional iterator that points just beyond the end of the sequence.
equal range Returns a pair of iterators such that the first one is equal to a given lower bound, and the second is equal to a given upper bound.
erase Function that can remove the element of the sequence pointed to by it or remove a range of elements.
find Returns an interator to the first element it finds matching a given value. If no match is found, the iterator is equal to end().
get_allocator Returns allocator.
insert Inserts an element, a repetition of elements, or the sequence. When inserting a single element, the iterator of the element is returned.
iterator Type definition that can serve as a bidirectional iterator for the sequence.
key_comp Determines the order of elements in a sequence.
key_compare Compares two sort keys to determine the relative order of any two elements in the sequence.
key_type Type definition for the sort key object in each element of the sequence.
lower_bound Returns an iterator that designates the lower bound of a given element value. If no element is found, end() is returned.
map Constructor for the Map object.
max_size Returns the length of the largest sequence the object can use.
multimap Constructor for the Multimap object.
multiset Constructor for Multiset.
operator[] Returns a reference to the element of the sequence at the declared position. Applies to Map object only.
rbegin Returns a reverse bidirectional iterator that points just beyond the end of the sequence.
reference Type definition for an object that can be a reference to an element of the sequence.
referent type Type definition of referent.
rend Returns a reverse bidirectional iterator that points to the first element of the sequence.
reverse_iterator Type definition that can serve as a reverse iterator for the sequence.
set Constructor for Set.
size Returns the length of the sequence.
size_type Type definition that describes an object that can represent the length of a sequence.
swap Swaps two sequences.
upper_bound Returns an iterator that designates the upper bound of a given element value. If no element is found, end() is returned.
value_comp Returns the order of elements in a sequence.
value_compare Compares the sort keys of two elements to determine their relative order in the sequence.
value_type Type definition for value_type.

A program example that puts some of this knowledge to work follows. It is quite simple and self-explanatory, but it demonstrates the basics of working with the Vector container class.

Example 13.4. Vector Program Example

// Vector program example
//
// Functions:
//    vector::push_back
//    vector::pop_back
//    vector::begin
//    vector::end
//    vector::iterator

#include <iostream>
#include <vector>

using namespace std ;

typedef vector<int> INTVECTOR;

void main(){

    INTVECTOR MyVector;

// Iterator is used to loop through the vector.
 INTVECTOR::iterator MyIterator;

// MyVector will contain [ 1, 2, 3 ]
MyVector.push_back(1) ;

MyVector.push_back(2) ;

MyVector.push_back(3) ;

// Erase element 3 in vector.
    MyVector.pop_back();
// MyVector will contain [ 1, 2 ] at this point
MyVector.push_back(4) ;
// MyVector now contains [ 1, 2, 4 ]

// Print contents of MyVector. Shows [1, 2, 4]
    cout << "Results = " ;

for (MyIterator = MyVector.begin();
MyIterator != MyVector.end();
        MyIterator++)
 {
   cout << *MyIterator;
   if (MyIterator != MyVector.end()-1) cout << ", ";
 }
 cout << endl ;
}
Results = 1, 2, 4
						

Share ThisShare This

Informit Network