Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
B.Eckel - Thinking in C++, Vol.2, 2nd edition.pdf
Скачиваний:
50
Добавлен:
08.05.2013
Размер:
2.09 Mб
Скачать

what happens when you’re holding onto an iterator (i.e. a pointer) and then you add the one additional object that causes the vector to reallocate storage and move it elsewhere. Your pointer is now pointing off into nowhere:

//: C04:VectorCoreDump.cpp

// How to break a program using a vector #include <vector>

#include <iostream> using namespace std;

int main() {

vector<int> vi(10, 0); ostream_iterator<int> out(cout, " "); copy(vi.begin(), vi.end(), out); vector<int>::iterator i = vi.begin(); cout << "\n i: " << long(i) << endl; *i = 47;

copy(vi.begin(), vi.end(), out);

//Force it to move memory (could also just add

//enough objects):

vi.resize(vi.capacity() + 1);

// Now i points to wrong memory: cout << "\n i: " << long(i) << endl;

cout << "vi.begin(): " << long(vi.begin()); *i = 48; // Access violation

} ///:~

If your program is breaking mysteriously, look for places where you hold onto an iterator while adding more objects to a vector. You’ll need to get a new iterator after adding elements, or use operator[ ] instead for element selections. If you combine the above observation with the awareness of the potential expense of adding new objects to a vector, you may conclude that the safest way to use one is to fill it up all at once (ideally, knowing first how many objects you’ll need) and then just use it (without adding more objects) elsewhere in the program. This is the way vector has been used in the book up to this point.

You may observe that using vector as the “basic” container in the earlier chapters of this book may not be the best choice in all cases. This is a fundamental issue in containers, and in data structures in general: the “best” choice varies according to the way the container is used. The reason vector has been the “best” choice up until now is that it looks a lot like an array, and was thus familiar and easy for you to adopt. But from now on it’s also worth thinking about other issues when choosing containers.

Inserting and erasing elements

The vector is most efficient if:

Chapter 15: Multiple Inheritance

177

1.You reserve( ) the correct amount of storage at the beginning so the vector never has to reallocate.

2.You only add and remove elements from the back end.

It is possible to insert and erase elements from the middle of a vector using an iterator, but the following program demonstrates what a bad idea it is:

//: C04:VectorInsertAndErase.cpp

// Erasing an element from a vector #include "Noisy.h"

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

int main() { vector<Noisy> v; v.reserve(11);

cout << "11 spaces have been reserved" << endl; generate_n(back_inserter(v), 10, NoisyGen()); ostream_iterator<Noisy> out(cout, " ");

cout << endl;

copy(v.begin(), v.end(), out);

cout << "Inserting an element:" << endl; vector<Noisy>::iterator it =

v.begin() + v.size() / 2; // Middle v.insert(it, Noisy());

cout << endl;

copy(v.begin(), v.end(), out);

cout << "\nErasing an element:" << endl; // Cannot use the previous value of it: it = v.begin() + v.size() / 2; v.erase(it);

cout << endl;

copy(v.begin(), v.end(), out); cout << endl;

} ///:~

When you run the program you’ll see that the call to reserve( ) really does only allocate storage – no constructors are called. The generate_n( ) call is pretty busy: each call to NoisyGen::operator( ) results in a construction, a copy-construction (into the vector) and a destruction of the temporary. But when an object is inserted into the vector in the middle, it must shove everything down to maintain the linear array and – since there is enough space – it does this with the assignment operator (if the argument of reserve( ) is 10 instead of eleven

Chapter 15: Multiple Inheritance

178

Соседние файлы в предмете Численные методы
  • #
    08.05.20133.99 Mб22A.Menezes, P.van Oorschot,S.Vanstone - HANDBOOK OF APPLIED CRYPTOGRAPHY.djvu
  • #
  • #
    08.05.20135.91 Mб24B.Eckel - Thinking in Java, 3rd edition (beta).pdf
  • #
  • #
    08.05.20136.09 Mб17D.MacKay - Information Theory, Inference, and Learning Algorithms.djvu
  • #
    08.05.20133.85 Mб15DIGITAL Visual Fortran ver.5.0 - Programmers Guide to Fortran.djvu
  • #
    08.05.20131.84 Mб12E.A.Lee, P.Varaiya - Structure and Interpretation of Signals and Systems.djvu