ilteris kaplan blog

Archive of blog posts since 2005

April 5, 2008

Wiki

Vectors

#wiki

Vectors

A 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.

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.

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, 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.

Key Concept: vectorS Grow Dynamically

A central property of vectors (and the other library containers) is that they are required to be implemented so that it is efficient to add elements to them at run time. Because vectors grow efficiently, it is usually best to let the vector grow by adding elements to it dynamically as the element values are known.

vector is not a type; it is a template that we can use to define any number of types. Each of vector type specifies an element type. Hence, vector and vector are types.

|v.empty() |Returns true if v is empty; otherwise returns false| |v.size()|Returns number of elements in v| |v.push_back(t)|Adds element with value t to end of v| |v[n]|Returns element at position n in v| |v1 = v2|Replaces elements in v1 by a copy of elements in v2| |v1 == v2|Returns TRue if v1 and v2 are equal| |!=, <, <=, >, and >=|Have their normal meanings|

The size of a vector

To use size_type, we must name the type in which it is defined. A vector type always includes the element type of the vector:


 vector<int>::size_type        // ok
     vector::size_type            // error

Adding Elements to a vector

The 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 vector

Objects 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.

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.

Even if ivec is empty, this for loop executes correctly. If ivec is empty, the call to size returns 0 and the test in the for compares ix to 0. Because ix is itself 0 on the first trip, the test would fail and the loop body would not be executed even once.

Continue Reading

Back to Archive