7 2 1Templates Templates allow you to construct both functions and classes based on types that have not yet been stated.Thus, templates are a powerful tool for automating program code ge
Trang 1S O L U T I O N S 719
if( count < 0 || count > 15)
{
cout << "Invalid input!"
<< " Shifting by one bit position.\n";
count = 1;
}
cout << "\nThe bit pattern of x << "
<< setw(2) << count << " : ";
putbits( x << count);
cout << "\nThe bit pattern of x >> "
<< setw(2) << count << " : ";
putbits( x >> count);
cout << "\nRepeat (y/n)? ";
cin >> yn;
while( (yn | 0x20) != 'y' && yn != 'n')
;
}while( yn == 'y');
return 0;
}
//
-// Output the bit pattern of n (only the 16 lower bits)
void putbits( unsigned int n )
{
int i;
for( i = 15; i >= 0 ; i)
{
cout << (char)( ((n>>i) & 1) + '0'); // i-th bit
if( i % 4 == 0 && i > 0) // and after 4 bits
cout << ' '; // one blank
}
}
Exercise 2
//
// Swap bits in bit positions 5 and 6,
// 0 and 4, 1 and 3 for all characters
// except control characters
// Modules: hide_t.cpp, swapbits.cpp
//
// Call: hide_t [ < sourcefile ] [ > destfile ]
//
Trang 2-720 C H A P T E R 3 1 M A N I P U L A T I N G B I T S
#include <iostream>
using namespace std;
int swapbits( int ch, int bitnr1, int bitnr2); // Prototype
int main() // Encrypt data {
int c;
while( (c = cin.get()) != EOF) {
if( c >= 32) // Control character? {
c = swapbits(c, 5, 6); // Swap bits
c = swapbits(c, 0, 4);
c = swapbits(c, 1, 3);
} cout << c;
} return 0;
}
//
// within an integer
// Arguments: The integer and two bit positions
// Returns: The new value
//
-int swapbits( -int x, -int bitnr1, -int bitnr2) { // To swap two bits in x int newx, mask1, mask2;
int msb = 8 * sizeof(int) - 1; // Highest bit position
if( bitnr1 < 0 || bitnr1 > msb ||
bitnr2 < 0 || bitnr2 > msb) return x; // Return, if bit position is invalid
mask1 = (1 << bitnr1); // Shift 1 to position bitnr1 mask2 = (1 << bitnr2); // Shift 1 to position bitnr2
newx = x & ~(mask1 | mask2); // Delete both bits
if( x & mask1 ) newx |= mask2; // Swap bits
if( x & mask2 ) newx |= mask1;
return( newx);
}
Trang 37 2 1
Templates
Templates allow you to construct both functions and classes based on types that have not yet been stated.Thus, templates are a powerful tool for automating program code generation
This chapter describes how to define and use function and class templates In addition, special options, such as default arguments,
specialization, and explicit instantiation are discussed
Trang 4722 C H A P T E R 3 2 T E M P L A T E S
■ FUNCTION AND CLASS TEMPLATES
Template and instantiation
Template
Instantiation for
Type long Type int Type char
Trang 5F U N C T I O N A N D C L A S S T E M P L A T E S 723
䊐 Motivation
As a programmer you will often be faced with implementing multiple versions of similar functions and classes, which are needed for various types
A class used to represent an array of intvalues is very similar to a class representing
an array of doublevalues, for example The implementation varies only in the type of elements that you need to represent Operations performed with elements, such as search and sort algorithms, must be defined separately for each type
C++ allows you to define templates—parameterized families of related functions or
classes:
■ a function template defines a group of statements for a function using a parameter
instead of a concrete type
■ a class template specifies a class definition using a parameter instead of a concrete
type
A class template can provide a generic definition that can be used to represent various
types of arrays, for example During instantiation, that is, when a concrete type is defined,
an individual class is created based on the template definition
䊐 Advantages of Templates
Templates are powerful programming tools
■ A template need only be coded once Individual functions or classes are automat-ically generated when needed
■ A template offers a uniform solution for similar problems allowing type-inde-pendent code to be tested early in the development phase
■ Errors caused by multiple encoding are avoided
䊐 Templates in the Standard Library
The C++ standard library contains numerous class template definitions, such as the stream classes for input and output, string, and container classes The classes string,
istream,ostream,iostream, and so on are instantiations for the chartype The standard library also includes an algorithm library, which comprises many search and sort algorithms The various algorithms are implemented as global function tem-plates and can be used for any set of objects
Trang 6724 C H A P T E R 3 2 T E M P L A T E S
// stack.h : The class template Stack with // methods push() and pop()
// -template<class T>
class Stack
{
private:
T* basePtr; // Pointer to array int tip; // Stack tip
int max; // Maximum number of elements
public:
Stack(int n){ basePtr = new T[n]; max = n; tip = 0;} Stack( const Stack<T>&);
~Stack(){ delete[] basePtr; }
Stack<T>& operator=( const Stack<T>& );
bool empty(){ return (tip == 0); } bool push( const T& x);
bool pop(T& x);
};
template<class T>
bool Stack<T>::push( const T& x)
{ if(tip < max - 1) // If there is enough space {
basePtr[tip++] = x; return true;
} else return false;
}
template<class T>
bool Stack<T>::pop( T& x)
{ if(tip > 0) // If the stack is not empty {
x = basePtr{ tip]; return true;
} else return false;
}
■ DEFINING TEMPLATES
Class template Stack
Trang 7D E F I N I N G T E M P L A T E S 725
䊐 Defining Function Templates
The definition of a template is always prefixed by
template<class T>
where the parameter Tis a type name used in the definition that follows Although you must state the classkeyword,Tcan be any given type, such as an intordouble
Example: template <class T>
void exchange(T& x, T&y)
{
T help(x); x = y; y = help;
}
This defines the function template exchange() The parameter Trepresents the type
of variables, which are to interchange The name Tis common but not mandatory
䊐 Defining Class Templates
Example: template <class U>
class Demo
{
U elem; // etc
};
This defines the class template Demo<U> Both UandDemo<U>are treated like normal types in the class definition You simply need to state the name of the template, Demo, within the class scope
The methods of a class template are also parameterized via the future type Each method in a class template is thus a function template If the definition is external to the class template, function template syntax is used The method name is prefixed by the class template type and the scope resolution operator
The example on the opposite page illustrates this point by defining a stack template.
A stack is managed according to the last-in-first-out principle, lifo-principle for short; the
last element to be “pushed” onto the stack is the first to be removed, or “popped,” from the stack
The methods of a class template are normally defined in the same header file This ensures that the definition will be visible to the compiler, since it requires the definition
to generate machine code for concrete template arguments
Trang 8726 C H A P T E R 3 2 T E M P L A T E S
// stack_t.cpp: Testing a stack //
-#include <iostream>
#include <iomanip>
using namespace std;
#include "stack.h"
typedef Stack<unsigned> USTACK; // Stack for elements
// of type unsigned void fill( USTACK& stk );
void clear( USTACK& stk );
int main() {
USTACK ustk(256); // Create and fill fill( ustk); // the original stack.
USTACK ostk(ustk); // Copy.
cout << "The copy: " << endl;
clear( ostk); // Output and clear the copy cout << "The original: " << endl;
clear( ustk ); // Output, clear the original return 0;
} void fill( USTACK& stk ) {
unsigned x;
cout << "Enter positive integers (quit with 0):\n"; while( cin >> x && x != 0 )
if( !stk.push(x) ) {
cerr << "Stack is full!"; break;
} } void clear( USTACK& stk ) {
if(stk.empty()) cerr << "Stack is empty!" << endl;
else { unsigned x;
while( stk.pop(x)) cout << setw(8) << x << " ";
cout << endl;
} }
■ TEMPLATE INSTANTIATION
Sample program
Trang 9T E M P L A T E I N S T A N T I A T I O N 727
Defining a template creates neither a concrete function nor a class The machine code for functions or methods is not generated until instantiation
䊐 Instantiating Template Functions
A template function is instantiated when it is first called The compiler determines the
parameter type of Tby the function arguments
Example: short a = 1, b = 7;
exchange( a, b );
The template is first used to generate the exchange() function machine code for the
shorttype The template functions can be called after this step
This allows you to generate an exchange() template function for any type Given thatxandyare two doublevariables, the following statement
Example: exchange( x, y );
creates a second template function for the doubletype
䊐 Instantiation of Template Classes
The instantiation of a template class is performed implicitly when the class is used for the
first time, for example, when an object of the template class is defined
Example: Stack<int> istack(256); // implicit
This statement first creates the template class Stack<int>, generating the machine code of all methods for the inttype After this step has been completed, an istack
object of the Stack<int>type can be constructed
If a further template class, such as Stack<float>is created, the machine code gen-erated for the methods in this template class will be different from the machine code of theStack<int>methods
In other words, developing templates will not reduce the amount of machine code required for a program However, it does spare the programmer’s extra work required to develop multiple versions of functions and classes
Templates are double checked for errors by the compiler—once when the template
definition is compiled and again during instantiation The first check recognizes errors that are independent of the template parameters Errors in parameterization cannot be detected until instantiation if, for example, an operator for the template argument type has not been defined
Trang 10728 C H A P T E R 3 2 T E M P L A T E S
// stackn.h: Class Template Stack<T, n>
//
-template <class T, int n>
class Stack
{
private:
T arr[n]; // Array int tip; // Tip of stack int max; // Maximum number of elements
public:
Stack(){ max = n; tip = 0; };
bool empty(){ return (tip == 0); } bool push( const T& x);
bool pop(T& x);
};
template<class T, int n>
bool Stack<T, n>::push( const T& x)
{ if(tip < max - 1) {
arr[tip++] = x; return true;
} else return false;
}
template<class T, int n>
bool Stack<T, n>::pop(T& x )
{ if(tip > 0) {
x = arr{ tip]; return true;
} else return false;
}
■ TEMPLATE PARAMETERS
The Stack template with two template parameters