Demonstrating Vectors
Now here's a demonstration of the vector type. But wait! If you read the previous section, you probably noticed that I mentioned that templates are not classes; they're cookie cutters for classes. So what is vector? It's really a template. That means that you have to create a class based on the vector template. And when you do, you specify the type of data that the vector will hold.
Suppose you want to create a vector that can hold 10 integers. Here's an example:
#include <iostream> #include <vector> using namespace std; int main() { vector<int> storage(10); storage[0] = 10; storage[1] = 20; storage[2] = 30; for (int i=0; i<storage.size(); i++) { cout << storage[i] << endl; } }
Here's the output:
10 20 30 0 0 0 0 0 0 0
In this code, I created an instance of the class vector<int>, which is based on the vector template. I called the instance storage, and specified that it would hold 10 items. Then I accessed the elements just as I would an array. But by itself, this example really isn't any better than an array.
Vectors are better than arrays, however, because you don't have to specify a size up front. But when you do so, you have to use a different method of putting items into the vector. Here's a revised version where I don't specify the size up front, and I use the push_back function, which appends an item to the vector:
#include <iostream> #include <vector> using namespace std; int main() { vector<int> storage; storage.push_back(10); storage.push_back(20); storage.push_back(30); for (int i=0; i<storage.size(); i++) { cout << storage[i] << endl; } }
As you append items to the vector, the size will change. Thus, the call to size() in this example will return 3. Here's the output:
10 20 30
Not bad! But it gets better. The usual way of moving through a vector (and other containers) is by using an iterator. People tend to be confused by iterators, but they're really not complicated. An iterator is simply a pointer to an item inside the vector. That's all. But iterators are smart, and you can move about the vector. Here's an example:
#include <iostream> #include <vector> using namespace std; int main() { vector<int> storage; storage.push_back(10); storage.push_back(20); storage.push_back(30); vector<int>::iterator iter = storage.begin(); while (iter != storage.end()) { cout << *iter << endl; iter++; } }
This example creates an iterator called iter, and starts it out pointing to the beginning of the vector. But look carefully at the iterator's type. The type is vector<int>::iterator. Each container class has a member type called iterator. The container class in this case is vector<int>, so the iterator's type name is vector<int>::iterator.
The begin() function returns an iterator pointing to the beginning of the vector. The end() function returns an iterator pointing to the end of the vector. So I start at the beginning and perform a while loop, testing whether the iterator is at the end of the vector. If not, I print out the iterator. But notice I have to dereference the pointer by saying *iter. The iterator is really a pointer, remember, and so I use *iter to get to the contents.
Do you see what's happening? The iterator points to an item in the vector. That's all! Then, to move to the next item in the vector, I simply use iter++.
Here's the output:
10 20 30