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

for(int i3 = 0; i3 < count; i3++) for(int j = 0; j < sz; j++)

di[j];

cout << "deque[]" << clock() - ticks << endl; ticks = clock();

for(int i4 = 0; i4 < count; i4++) for(int j = 0; j < sz; j++)

di.at(j);

cout << "deque::at()" << clock()-ticks <<endl; // Demonstrate at() when you go out of bounds: di.at(vi.size() + 1);

} ///:~

As you’ll learn in the exception-handling chapter, different systems may handle the uncaught exception in different ways, but you’ll know one way or another that something went wrong with the program when using at( ), whereas it’s possible to go blundering ahead using operator[ ].

list

A list is implemented as a doubly-linked list and is thus designed for rapid insertion and removal of elements in the middle of the sequence (whereas for vector and deque this is a much more costly operation). A list is so slow when randomly accessing elements that it does not have an operator[ ]. It’s best used when you’re traversing a sequence, in order, from beginning to end (or end to beginning) rather than choosing elements randomly from the middle. Even then the traversal is significantly slower than either a vector or a deque, but if you aren’t doing a lot of traversals that won’t be your bottleneck.

Another thing to be aware of with a list is the memory overhead of each link, which requires a forward and backward pointer on top of the storage for the actual object. Thus a list is a better choice when you have larger objects that you’ll be inserting and removing from the middle of the list. It’s better not to use a list if you think you might be traversing it a lot, looking for objects, since the amount of time it takes to get from the beginning of the list – which is the only place you can start unless you’ve already got an iterator to somewhere you know is closer to your destination – to the object of interest is proportional to the number of objects between the beginning and that object.

The objects in a list never move after they are created; “moving” a list element means changing the links, but never copying or assigning the actual objects. This means that a held iterator never moves when you add new things to a list as it was demonstrated to do in vector. Here’s an example using the Noisy class:

//: C04:ListStability.cpp

// Things don't move around in lists #include "Noisy.h"

Chapter 15: Multiple Inheritance

185

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

int main() { list<Noisy> l;

ostream_iterator<Noisy> out(cout, " "); generate_n(back_inserter(l), 25, NoisyGen()); cout << "\n Printing the list:" << endl; copy(l.begin(), l.end(), out);

cout << "\n Reversing the list:" << endl; l.reverse();

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

cout << "\n Sorting the list:" << endl; l.sort();

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

cout << "\n Swapping two elements:" << endl; list<Noisy>::iterator it1, it2;

it1 = it2 = l.begin(); it2++;

swap(*it1, *it2); cout << endl;

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

cout << "\n Using generic reverse(): " << endl; reverse(l.begin(), l.end());

cout << endl;

copy(l.begin(), l.end(), out); cout << "\n Cleanup" << endl;

} ///:~

Operations as seemingly radical as reversing and sorting the list require no copying of objects, because instead of moving the objects, the links are simply changed. However, notice that sort( ) and reverse( ) are member functions of list, so they have special knowledge of the internals of list and can perform the pointer movement instead of copying. On the other hand, the swap( ) function is a generic algorithm, and doesn’t know about list in particular and so it uses the copying approach for swapping two elements. There are also generic algorithms for sort( ) and reverse( ), but if you try to use these you’ll discover that the generic reverse( ) performs lots of copying and destruction (so you should never use it with a list) and the generic sort( ) simply doesn’t work because it requires random-access iterators that list doesn’t provide (a definite benefit, since this would certainly be an expensive way to sort compared to list’s own sort( )). The generic sort( ) and reverse( ) should only be used with arrays, vectors and deques.

Chapter 15: Multiple Inheritance

186

Соседние файлы в предмете Численные методы
  • #
    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