1. Trang chủ
  2. » Công Nghệ Thông Tin

A Complete Guide to Programming in C++ part 78 docx

10 172 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 10
Dung lượng 247,9 KB

Nội dung

749 Containers This chapter describes standard class templates used to represent containers for more efficient management of object collections.These include ■ sequences, such as lists and double ended queues ■ container adapters, such as stacks, queues, and priority queues ■ associative containers, such as sets and maps, and ■ bitsets. Besides discussing how to manage containers, we will also be looking at sample applications, such as bitmaps for raster images, and routing techniques. chapter 33 750 ■ CHAPTER 33 CONTAINERS ■ CONTAINER TYPES Sequences and associative containers Arrays Stacks Queues etc. Sets Maps Bitsets Sequences Associative Containers Containers CONTAINER TYPES ■ 751 ᮀ What is a Container? Containers are used to store objects of the same type and provide operations with which these objects can be managed. These operations include object insertion, deletion, and retrieval. Memory is allocated for containers dynamically at runtime. Containers thus provide a safe and easy way to manage collections of objects. The C++ standard library provides various class templates for container management in the Containers Library. These classes can be categorized as follows: ■ sequential containers, or sequences, where the objects are arranged sequentially and access to an object can either be direct or sequential ■ associative containers, where the objects are generally organized and managed in a tree structure and can be referenced using keys. ᮀ Sequences Sequential containers are distinguished by the operations defined for them, which are either generic or restricted. Restricted operations, such as appending at the end of a con- tainer, have constant runtimes. That is, the runtime is proportional to a fixed period of time and does not depend on the number of objects in the container. The following are sequential containers: ■ arrays, which provide the same operations as C arrays but increase and decrease in size dynamically, in contrast to C arrays ■ queues, which are managed on the FIFO (First In First Out) principle. The first element to be inserted is also removed first ■ stacks, which are managed on the LIFO (Last In First Out) principle. The last element to be inserted is removed first. ᮀ Associative Containers and Bitsets Associative containers comprise sets, which allow quick access to objects via sortable keys, and maps, which maintain efficient object/key pairs. There are also so-called bitsets, which represent bit sequences of a given length and provide bitwise operators, with which bits can be manipulated. 752 ■ CHAPTER 33 CONTAINERS ■ SEQUENCES Operations for sequences Class Template Time needed to insert or remove an object vector<class T, class Allocator = allocator<T> > At the end: constant. At the beginning or in the middle: linear. In all positions: constant. At the beginning or end: constant. In the middle: linear list<class T, class Allocator = allocator<T> > deque<class T, class Allocator = allocator<T> > Container adapters Class Template Insertion Deletion stack<class T, class Container = dequeue<T> > at the end at the end queue<class T, class Container = dequeue<T> > at the end at the beginning at the beginning priority_queue<class T, class Container = vector<T>, Compare=less<T> > priority based Sequences and header files Container Header File vector<T, Allocator> list<T, Allocator> deque<T, Allocator> stack<T, Container> queue<T, Container> priority_queue<T, <vector> <list> <deque> <stack> <queue> <queue> Container, Compare > SEQUENCES ■ 753 ᮀ Representing Sequences The Containers Library defines so-called container classes representing containers. These are class templates parameterized by the type T of the objects to be managed. Three basic class templates are defined for sequences. ■ The container class vector<T, Allocator> supports standard array opera- tions, such as direct access to individual objects via the subscript operator [], and quick appending and deletion at the end of the container. However, the run- time for insertion and deletion at the beginning or in the middle of the container is linear, that is, proportional to the number of objects stored in the container. ■ The container class list<T, Allocator> provides functionality that is typi- cal for double linked lists. This includes quick insertion and deletion at any given position. General list operations, such as sorting and merging, are also defined. ■ The container class deque<T, Allocator> (double ended queue, pronounced “deck”) provides direct access via a subscript operator, just like a normal array, but offers optimized insertion and deletion at the beginning and end of the con- tainer. The same operations in the middle of a container have a linear runtime. The second template parameter is used for any storage allocation to be performed. The storage management is represented by a so-called allocator class, which is parameterized by an object of type T. It enables dynamic memory allocation for objects of type T. The default value of the template parameter is the standard allocator class allocator<T> that uses the new and delete operators to allocate and release memory. ᮀ Adapter Classes The basic sequence classes are used to construct so-called adapter classes. An adapter class expects a sequence as a template argument and stores the sequence in a protected data member. The opposite page shows various adapter classes. The priority_queue template represents priority queues. The relationship between the keys used to manage the priori- ties is defined in the comparator class, Compare. The default value of the template parameter is the predefined comparator class, less<T>, which uses the lesser than oper- ator < for type T. 754 ■ CHAPTER 33 CONTAINERS // Outputs a list containing integers. // #include <list> #include <iostream> using namespace std; typedef list<int> INTLIST; // int list int display(const INTLIST& c) { int z = 0; // Counter list<int>::const_iterator pos; // Iterator for( pos = c.begin(); pos != c.end(); pos++, z++) cout << *pos << endl; cout << endl; return z; } // iterat_t.cpp: Outputs an array of accounts. // #include <vector> #include <iostream> using namespace std; #include "account.h" typedef vector<Account> AccVec; // Account vector void display(const AccVec& v) { AccVec::const_iterator pos; // Iterator for( pos = v.begin(); pos < v.end(); pos++) pos->display(); cout << endl; } ■ ITERATORS Iterating lists Iterating vectors ITERATORS ■ 755 ᮀ Positioning and Iterating in Containers Each object in a container occupies the specific position where it was stored. To allow you to work with the objects in a container, the positions of the objects in the container must be accessible. There must therefore be at least one mechanism that allows: ■ read and/or write access to the object at any given position and ■ moving from the position of one object to the position of the next object in the container. This situation should be familiar from your experience of working with pointers. Given that i is the index of an element in an array v, (v+i) is its address, *(v+i) the array element itself, and (v + (++i)) the address of the next array element. Iterators were introduced in C++ to provide a uniform model for positioning and iter- ation in containers. An iterator can thus be regarded as an abstraction of a pointer. ᮀ Iterator Types Two types of iterators are important in this context: ■ bidirectional iterators, which can be shifted up by the increment operator ++ and down with the decrement operator , and use the operators * and -> to provide write or read access to objects ■ random access iterators, which are bidirectional iterators that can additionally perform random positioning. The subscript operator [] was overloaded for this purpose, and the operations defined for pointer arithmetic, such as addition/sub- traction of integers or comparison of iterators, are defined. The container classes vector<T> and deque<T> have random access iterators and the container class list<T> has bidirectional iterators. ᮀ Iterator Classes The types iterator and const_iterator are defined in all the above classes to rep- resent iterators. An iterator belonging to one of these classes can reference constant or non-constant objects. The methods begin() and end() are also defined. The begin() method accesses the first position and end() accesses the position after the last container object. Containers that belong to adapter classes offer only restricted access to the beginning or end. You cannot use iterators to walk through them. 756 ■ CHAPTER 33 CONTAINERS // sortVec.h: The Class Template SortVec representing // a sorted vector. // #include <vector> // For class template vector<T> #include <functional> // For comparator class less<T> using namespace std; template <class T, class Compare = less<T> > class SortVec : public vector<T> { public: SortVec() { } SortVec(int n, const T& x = T()); void insert(const T& obj); // in sorted order int search(const T& obj); void merge(const SortVec<T>& v); }; // sortv_t.cpp : Tests the template SortVec. // #include "sortVec.h" typedef SortVec<int> IntSortVec; int main() { IntSortVec v, w; // Default constructor v.insert(2); v.insert(7); v.insert(1); int n = v.search(7); w.insert(3); w.insert(9); v.merge(w); return 0; } // The array v then contains the elements: 1 2 3 7 9 ■ DECLARING SEQUENCES The derived container class sortVec<T, Compare> Using the container class sortVec DECLARING SEQUENCES ■ 757 ᮀ Constructors of vector, list, and deque The container classes vector, list, and deque define three constructors and a copy constructor with which sequences can be created. Their functionality is similar for the various classes and is discussed in the following section using the vector class as an example. The statement Example: vector<Account> v; declares an empty container v for objects of the Account type. You can then insert individual objects into the container. However, you can also declare a container and fill it with a predefined number of object copies. Example: Fraction x(1, 1); vector<Fraction> cont(100, x); This defines the container cont with 100 Fraction type objects, and fills it with the object x. If the second argument is not supplied, each of the 100 objects is initialized by the default constructor. Finally, you can initialize a container with a part of another container. To do so, you must state a range of iterators. Example: vector<double> v(first,last); The arguments first and last are iterators in an existing container. The new con- tainer, v, is initialized using objects in the range [first, last): this includes all the objects between the positions first (including first) and last (excluding last). ᮀ Constructors for Adapter Classes Only a default constructor and the copy constructor are defined for adapter classes. Given that wait is a predefined queue of the container class queue<double>, the fol- lowing statement Example: queue<double> w(wait); creates a new queue, w, and uses the object wait to initialize it. The opposite page shows the derived container class sortVec, which is used to rep- resent sorted, dynamic arrays. The class is parameterized by the type T of array elements. The second template parameter is a comparator class, which represents a comparison cri- terion for sorting. 758 ■ CHAPTER 33 CONTAINERS Method Effect void push_back(const T&x); Adds x at the end of the sequence. Adds x before the first element of the sequence. Inserts x after position pos and returns the position of the newly inserted element. Inserts n copies of x after position pos and returns the number of inserted elements. Inserts all elements from range [first,last) after position pos into the sequence. void push_front(const T&x); iterator insert(iterator pos, const T& x = T() ); size_type insert(iterator pos, size_type n, const T& x) void insert(iterator pos, InputIterator first InputIterator last) // Method insert() adds a new object at the end // of the vector and reorganizes in ascending order. // template <class T, class Compare > void SortVec<T, Compare>::insert(const T& obj) { SortVec::iterator pos, temp; push_back(obj); // Add at the end. pos = end(); pos ; // Last position while (pos > begin()) // Sort: { if( obj < *pos) // Swap: { temp = pos; *(++temp) = *pos; *pos = obj; } else break; } } ■ INSERTING IN SEQUENCES Inserting methods Method insert() of the derived container class SortVec . The default value of the template parameter is the standard allocator class allocator<T> that uses the new and delete operators to allocate and release memory. ᮀ Adapter Classes The basic. can initialize a container with a part of another container. To do so, you must state a range of iterators. Example: vector<double> v(first,last); The arguments first and last are iterators. in the container. The following are sequential containers: ■ arrays, which provide the same operations as C arrays but increase and decrease in size dynamically, in contrast to C arrays ■ queues,

Ngày đăng: 06/07/2014, 17:21

TỪ KHÓA LIÊN QUAN