3.3. Library vector TypeA vector is a collection of objects of a single type, each of which has an associated integer index. As with strings, the library takes care of managing the memory associated with storing the elements. We speak of a vector as a container because it contains other objects. All of the objects in a container must have the same type. We'll have much more to say about containers in Chapter 9. To use a vector, we must include the appropriate header. In our examples, we also assume an appropriate using declaration is made: #include <vector> using std::vector; A vector is a class template. Templates let us write a single class or function definition that can be used on a variety of types. Thus, we can define a vector that holds strings, or a vector to hold ints, or one to hold objects of our own class types, such as Sales_items. We'll see how to define our own class templates in Chapter 16. Fortunately, we need to know very little about how templates are defined in order to use them. To declare objects of a type generated from a class template, we must supply additional information. The nature of this information depends on the template. In the case of vector, we must say what type of objects the vector will contain. We specify the type by putting it between a pair of angle brackets following the template's name: vector<int> ivec; // ivec holds objects of type int vector<Sales_item> Sales_vec; // holds Sales_items As in any variable definition, we specify a type and a list of one or more variables. In the first of these definitions, the type is vector<int>, which is a vector that holds objects of type int. The name of the variable is ivec. In the second, we define Sales_vec to hold Sales_item objects.
3.3.1. Defining and Initializing vectorsThe vector class defines several constructors (Section 2.3.3, p. 49), which we use to define and initialize vector objects. The constructors are listed in Table 3.4.
Creating a Specified Number of ElementsWhen we create a vector that is not empty, we must supply value(s) to use to initialize the elements. When we copy one vector to another, each element in the new vector is initialized as a copy of the corresponding element in the original vector. The two vectors must hold the same element type: vector<int> ivec1; // ivec1 holds objects of type int vector<int> ivec2(ivec1); // ok: copy elements of ivec1 into ivec2 vector<string> svec(ivec1); // error: svec holds strings, not ints We can initialize a vector from a count and an element value. The constructor uses the count to determine how many elements the vector should have and uses the value to specify the value each of those elements will have: vector<int> ivec4(10, -1); // 10 elements, each initialized to -1 vector<string> svec(10, "hi!"); // 10 strings, each initialized to "hi!"
Value InitializationWhen we do not specify an element initializer, then the library creates a value initialized element initializer for us. This library-generated value is used to initialize each element in the container. The value of the element initializer depends on the type of the elements stored in the vector. If the vector holds elements of a built-in type, such as int, then the library creates an element initializer with a value of 0:
vector<string> fvec(10); // 10 elements, each initialized to 0
If the vector holds elements of a class type, such as string, that defines its own constructors, then the library uses the value type's default constructor to create the element initializer:
vector<string> svec(10); // 10 elements, each an empty string
There is a third possibility: The element type might be of a class type that does not define any constructors. In this case, the library still creates a value-initialized object. It does so by value-initializing each member of that object. 3.3.2. Operations on vectorsThe vector library provides various operations, many of which are similar to operations on strings. Table 3.5 lists the most important vector operations.
The size of a vectorThe empty and size operations are similar to the corresponding string operations (Section 3.2.3, p. 83). The size member returns a value of the size_type defined by the corresponding vector type.
vector<int>::size_type // ok vector::size_type // error Adding Elements to a vectorThe push_back operation takes an element value and adds that value as a new element at the back of a vector. In effect it "pushes" an element onto the "back" of the vector: // read words from the standard input and store them as elements in a vector string word; vector<string> text; // empty vector while (cin >> word) { text.push_back(word); // append word to text } This loop reads a sequence of strings from the standard input, appending them one at a time onto the back of the vector. We start by defining text as an initially empty vector. Each trip through the loop adds a new element to the vector and gives that element the value of whatever word was read from the input. When the loop completes, text will have as many elements as were read. Subscripting a vectorObjects in the vector are not named. Instead, they can be accessed by their position in the vector. We can fetch an element using the subscript operator. Subscripting a vector is similar to subscripting a string (Section 3.2.3, p. 87). The vector subscript operator takes a value and returns the element at that position in the vector. Elements in a vector are numbered beginning with 0. The following example uses a for loop to reset each element in the vector to 0: // reset the elements in the vector to zero for (vector<int>::size_type ix = 0; ix != ivec.size(); ++ix) ivec[ix] = 0; Like the string subscript operator, the vector subscript yields an lvalue so that we may write to it, which we do in the body of the loop. Also, as we do for strings, we use the size_type of the vector as the type for the subscript.
Subscripting Does Not Add ElementsProgrammers new to C++ sometimes think that subscripting a vector adds elements; it does not: vector<int> ivec; // empty vector for (vector<int>::size_type ix = 0; ix != 10; ++ix) ivec[ix] = ix; // disaster: ivec has no elements
This code intended to insert new 10 elements into ivec, giving the elements the values from 0 through 9. However, ivec is an empty vector and subscripts can only be used to fetch existing elements. The right way to write this loop would be for (vector<int>::size_type ix = 0; ix != 10; ++ix) ivec.push_back(ix); // ok: adds new element with value ix
![]() |