A Complete Guide to Programming in C++ part 75 potx

10 266 0
A Complete Guide to Programming in C++ part 75 potx

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

Thông tin tài liệu

SOLUTIONS ■ 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 // // hide_t.cpp: Filter to encrypt data. // 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 ] // 720 ■ CHAPTER 31 MANIPULATING BITS #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; } // // swapbits.cpp: The function swapbits() swaps two bits // 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); } 721 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. chapter 32 722 ■ CHAPTER 32 TEMPLATES ■ FUNCTION AND CLASS TEMPLATES Template and instantiation Template Instantiation for Type long Type int Type char FUNCTION AND CLASS TEMPLATES ■ 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 int values is very similar to a class representing an array of double values, 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 char type. 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. 724 ■ CHAPTER 32 TEMPLATES // 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 DEFINING TEMPLATES ■ 725 ᮀ Defining Function Templates The definition of a template is always prefixed by template<class T> where the parameter T is a type name used in the definition that follows. Although you must state the class keyword, T can be any given type, such as an int or double. 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 T represents the type of variables, which are to interchange. The name T is common but not mandatory. ᮀ Defining Class Templates Example: template <class U> class Demo { U elem; . . . // etc. }; This defines the class template Demo<U>. Both U and Demo<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. 726 ■ CHAPTER 32 TEMPLATES // 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 TEMPLATE INSTANTIATION ■ 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 T by 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 short type. The template functions can be called after this step. This allows you to generate an exchange() template function for any type. Given that x and y are two double variables, the following statement Example: exchange( x, y ); creates a second template function for the double type. ᮀ 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 int type. 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 the Stack<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. 728 ■ CHAPTER 32 TEMPLATES // 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 . 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. output, string, and container classes. The classes string, istream, ostream, iostream, and so on are instantiations for the char type. The standard library also includes an algorithm library, which. 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

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

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan