390 likes | 463 Views
Version 1.0. Programming Techniques Course. Version 1.0. Chapter 11 – Templates And STL. Motivation. A function for finding minimum value int min( int a, int b) { return (a>b ? a : b) } This is good for integers For floats we will need another function
E N D
Version 1.0 Programming Techniques Course
Version 1.0 Chapter 11 –Templates And STL
Motivation • A function for finding minimum value int min(int a, int b) { return (a>b ? a : b) } • This is good for integers • For floats we will need another function float min(float a, float b) { return (a>b ? a : b) } • Can we parameterize this function with a type? • Towards Generic Programming • Like objects are generalized into classes, we would like to generalize classes and functions into templates.
Motivation • Even creating a macro out of it will not work in certain cases #definemin(a, b) ((a)>(b) ? (a) : (b)) • It will work for min(5, 10); min(5.0, 10.0) • Think of an example when it will not work …
Function Template • Preserving the semantics of a function • Automatically generated instance of a function, varying by type • The programmer parameterizes all or a subset of the types in the interface • The function implementation remains invariant over a set of function instances, each handling a unique data type template <class Type> Type min(Type a, Type b) { return ( a>b ? a : b); } Template parameter List
Template Syntax • template <class Type> • This line states that everything in the following declaration or definition is under the subject of the template. • In the brackets goes a list of “placeholders variables.” • In almost all cases, they will be specified with either the typename or class keywords. • Placeholder variables have one value within each template declaration. • Think of them as being replaced by whatever type you specify the template to be.
Class Templates • Creating a class, where a type or value is parameterized • Motivation • A bag (of what?) • How would we implement generic code for this problem? • An array of pointers to base class • Each type would have to inherit from the basic type • May be a problematic solution • Homogeneous vector can be achieved by a template solution • The template class defines a bag of elements once, in a general way • Programs using bags can instantiate separate bag classes for specific types of elements as necessary
Problem Solution: Templates • Template class for a data structure uses a .h file and, instead of a .cpp file, a .template file • When an object of a data structure type is instantiated, the type of data object it stores is specified • If the class for that object does not already exist, the class is instantiated at compile time • Then the object from that class is instantiated
Bags With and Without Templates • Differences between .template, .cpp files: • Occurrences of BagOfItems :: are replaced by Bag<Item> :: • Member functions, constructors, destructor are preceded by template<class Item> • Constructors are Bag; destructor is ~Bag • Assumption:Item is a class • See use of NULL in add, getOne
Instantiating Bag Objects Bag<int> bag(40); // statically allocated bag for 40 ptrs to int Bag<int> *bagPtr = new Bag<int>(60); // bagPtr holds the // address of a dynamically allocated bag that stores up // to 60 pointers to int Bag< Bag<int> > x(25); // statically allocated bag x can hold 25 // pointers to bags, each of which can hold pointers to int Bag< Bag<int > > *y = new Bag< Bag<int > > (30); // y holds // the address of a dynamically allocated bag that stores // up to 30 pointers to bags of pointers to int
Instantiating Bag Objects • When Bag<Bag<int>> b = new Bag<Bag<int>>(30); is first encountered: • First, the class Bag<int> is instantiated • Then the class Bag<Bag<int>> is instantiated • Then the object b is instantiated • When Bag<int> and Bag<Bag<int>> are encountered subsequently, the classes already exist
Using Bag Objects • Suppose a bag has been declared using Bag<int> b(20); • Member functions can be invoked on b in the normal fashion • Only pointers to int can be stored in b • Values returned by b.getOne( ) are always of type int* • Outside the class definition, Bag as a type name is changed to Bag<Item> • Rule holds even in the portion of the .h file where prototypes of non-member functions are declared; each of these prototypes is preceded by the prefix template <class Item> • In Bag.template, constructor and destructor names are still Bag, ~Bag
OrderedList.h #include “List.h” template <class Item> class OrderedList { public: OrderedList(unsigned int capacity = MAX_LIST); // constructor for // an empty ordered list that can hold up to capacity items; default // size is defined in List.h ~OrderedList( ); // destructor bool isEmpty( ) const; // true if list is empty, false otherwise
OrderedList.h int getLength( ) const; // returns the current size of the list // remove the value at location pos, and return it; precondition: // pos must be a legal list position Item remove (unsigned int pos); // return value at pos without modifying the list; precondition: // pos must be a legal list position Item retrieve (unsigned int pos) const; // cont’d..
OrderedList.h // insert item at appropriate pos’n in list void insert (Item item); // return pos’n of first occurrence of item, or -1 if item isn’t found int find (Item item) const; private: List<Item> m_container; // to hold the list of Items }; // end of header file
OrderedList.template #include <stdlib.h> template <class Item> OrderedList<Item> :: OrderedList (unsigned int capacity ) : m_container(capacity) { } template <class Item> OrderedList<Item> :: ~OrderedList ( ) { } // cont’d..
OrderedList.template template <class Item> bool OrderedList<Item> :: isEmpty( ) const { return m_container.isEmpty( ); } template <class Item> int OrderedList<Item> :: getLength( ) const { return m_container.getLength( ); } // cont’d..
OrderedList.template template <class Item> Item OrderedList<Item> :: remove (unsigned int pos) { return m_container.remove(pos); } template <class Item> Item OrderedList<Item> :: retrieve (unsigned int pos) const { return m_container.retrieve(pos); } // cont’d..
OrderedList.template template <class Item> void OrderedList<Item> :: insert (Item item) { unsigned int k; for ( k = 1; k <= getLength( ); k++ ) if ( item < retrieve(k) ) break; m_container.insert( k, item ); } // cont’d..
OrderedList.template template <class Item> int OrderedList<Item> :: find (Item item) const { unsigned int k; for ( k=1; k <= getLength( ); k++ ) if ( item == retrieve(k) ) return k; return –1; } // end of OrderedList implementation
STL – Why? • Reuse. • Reusable core components. • The programmer can focus on application development, and rely on for portability of components such as: strings, containers, algorithms (sort, search, etc.) and I/O streams. • STL had been designed with efficiency in mind • Better maintainability
STL Overview • For best Generality and Reusability, most of STL’s components are supplied as templates (functions and classes). • Three main component groups: • Containers - contain and organize other objects. • Iterators - provide a means of sequencing through the elements of a container in some order. • Algorithms - perform certain operations on containers’ elements. • Those components are independent of each other, pluggable, and exchangeable, through generic interface
Containers – Overview • An STLcontainer is an object that manages a collection of elements. • Different containers, with efficiency considerations • For search, operator== is required • For ordering, relational operators are needed, i.e. operator< is required • With common, generic interface • Also, default constructor, copy constructor, copy assignment operator and destructor are needed. • Sequence containers • Ordered collection (vector, deque, list) • Associative containers • Sorted collection (map, multimap, set and multiset) – fast retrieval
Containers Common Functionality • Common member functions for all STL containers: • empty– returns true if there are no elements in the container, otherwise returns false. • size– returns the number of elements currently in the container. • max_size– returns the maximum number of elements for a container. • erase– erase one or more elements from the container. • clear– erase all elements from the container. • swap– swaps the elements of two containers.
Iterators • The containers provide iteratorclasses, enabling element iteration and access functionality in a common and general interface
Algorithms Overview – cont’d • Algorithms are designed to be a “plug-in” to work on any container • Search algorithms • find, find_if, count, count_if, search, binary_search, etc. • Sorting algorithms • sort, merge, partition, etc. • Other modifying sequence algorithms • Relational & minimum / maximum algorithms • More…
Container of T Generic Algorithm Iterator generates uses Interconnectivity of Components • The connections between iterators, containers and algorithms: • Containers provide iterators as part of their interface. • Algorithms are defined in terms of iterators. • There is no direct connection between algorithms and containers. • The use of iterators enables writing generic algorithms which are applicable to any container class that provides a standard iterator.