1 / 57

Engineering Problem Solving with C++, Etter/Ingber

Engineering Problem Solving with C++, Etter/Ingber. Chapter 10 Additional Topics in Programming with Classes. Programming with Classes. Introduction to Generic Programming Recursion Class Templates Inheritance virtual Methods. function templates overloading operators friend functions.

ulmer
Download Presentation

Engineering Problem Solving with C++, Etter/Ingber

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Engineering Problem Solving with C++, Etter/Ingber Chapter 10 Additional Topics in Programming with Classes Engineering Problem Solving with C++, Second Edition. J. Ingber

  2. Programming with Classes • Introduction to Generic Programming • Recursion • Class Templates • Inheritance • virtual Methods Engineering Problem Solving with C++, Second Edition. J. Ingber

  3. function templates overloading operators friend functions Introduction to generic programming Engineering Problem Solving with C++, Second Edition. J. Ingber

  4. Generic Programming • Generic programming supports the implementation of a type independent algorithm. • Type independent algorithms can be defined in C++ using the keyword template, and at least one parameter. • The compiler generates a unique instance of the template for each specified type. Engineering Problem Solving with C++, Second Edition. J. Ingber

  5. Function Templates • A function template is a parameterized function definition. Syntax: template<typename identifier [,typename identifier,…] > return-type function name(parameter list) { …} Example: template<typename Dtype> void swapTwo(Dtype& a, Dtype& b) { Dtype temp = a; a = b; b = temp; } Engineering Problem Solving with C++, Second Edition. J. Ingber

  6. Instantiating Templates Example: template<typename Dtype& a, Dtype& b> void swapTwo(Dtype& a, Dtype& b); //prototype … int main() { double x(1.0), y(5.7); char ch1('n'), ch2('o'); swapTwo(x,y); swapTwo(ch1, ch2); cout << x << ',' << y << endl << ch1 << ch2 << endl; ... Output: 5.7, 1.0 on Engineering Problem Solving with C++, Second Edition. J. Ingber

  7. Overloading Operators • Allows a programmer defined data type to be used in the same way that a predefined data type is used. • Definitions for overloaded operators are included in the class definition. • keyword operator is used followed by the operator. • the operator must be one of the predefined C++ operators. • Only predefined operators may be overloaded. • All predefined operators except( . :: .* ?: sizeof) may be overloaded. Engineering Problem Solving with C++, Second Edition. J. Ingber

  8. Complex Number Class • A complex number is a number that has two components; the real component and the imaginary component. • a + bi • Arithmetic is defined as follows: • (a + bi) + (c + di) = (a + c) + (b + d)i • (a + bi) - (c + di) = (a - c) + (b - d)i • (a + bi) * (c + di) = (ac - bd) + (ad + bc)i • (a + bi) / (c + di) = (ac + bd) / (c**2+d**2) + • [ (bc -ad) /(c**2+d**2)]i Engineering Problem Solving with C++, Second Edition. J. Ingber

  9. Class Declaration class complex { public: complex(); complex(double,double); void print(ostream&); void input(istream&); complex operator+(complex) const; complex operator-(complex) const; complex operator*(complex) const; complex operator/(complex) const; private: double real, imag; }; Engineering Problem Solving with C++, Second Edition. J. Ingber

  10. Implementation - constructors • complex::complex() • { //default constructor • real=imag=0; • } • complex :: complex(double r, double im) • { • real = r; • imag = im; • } Engineering Problem Solving with C++, Second Edition. J. Ingber

  11. Implementation – Overloaded Operators • complex complex::operator+(complex c) const • { • complex temp; • temp.real = real + c.real; • temp.imag = imag + c.imag; • return temp; • } Engineering Problem Solving with C++, Second Edition. J. Ingber

  12. Implementation - Continued • complex complex::operator/(complex c) const • { • complex temp; • temp.real = (real*c.real + imag*c.imag)/ • ( pow(c.real,2) + pow(imag,2) ); • temp.imag = (imag*c.real - real*c.imag)/ • ( pow(c.real,2) + pow(imag,2) ); • return temp; • } Engineering Problem Solving with C++, Second Edition. J. Ingber

  13. Practice! – Implement the * operator(a + bi) * (c + di) = (ac - bd) + (ad + bc)i complex complex::operator*(complex c) const { complex temp; temp.real = real*c.real – imag*c.imag; temp.imag = real*c.imag + imag*c.real; return temp; } Engineering Problem Solving with C++, Second Edition. J. Ingber

  14. Test Program complex c1, c2, c3; //declare three complex variables c1.input(cin); c2.input(cin); //test addition c3 = c1 + c2; // using overloaded operator + cout << endl << "c1 + c2 is "; c3.print(cout); //test division c3 = c1 / c2; // using overloaded operator / cout << endl << "c1 / c2 is "; c3.print(cout); cout << endl; Engineering Problem Solving with C++, Second Edition. J. Ingber

  15. Sample Output • Using the following input: 4.4 1.5 3.5 -2.5 • The expected output from our test program will be: c1 + c2 is 7.9 + -1i c1 / c2 is 0.62973 + 0.878378i Engineering Problem Solving with C++, Second Edition. J. Ingber

  16. Variations • Overloading Operators as: • member functions • friend functions • top level functions Engineering Problem Solving with C++, Second Edition. J. Ingber

  17. Member Functions • binary operators (ie +,-, * ) • member function requires one argument • the left hand operand is the object invoking the operator • unary operator • member function requires no arguments • assumed to be prefix version of operators ++ and – • postfix versions of operators ++ and – are not covered in this text • Disadvantages • first argument must be an objectof the class Engineering Problem Solving with C++, Second Edition. J. Ingber

  18. Example – class complex • In complex.h • complex operator +(complex c); • operator + implemented in complex.cpp • In a client program complex a, b, c; c = a + b; //a is calling object, b is argument c = a + 54.3; //OK, constructor is called to // convert 54.3 to complex object c = 54.3 + a // is not allowed Engineering Problem Solving with C++, Second Edition. J. Ingber

  19. Friend Functions • binary operators • friend function requires two arguments • unary operator • friend function requires one argument • Disadvantage • A friend function is NOT a member function • Friend functions violate a strict interpretation of object oriented principals (implementation is hidden) • Recommended for operator overloading only Engineering Problem Solving with C++, Second Edition. J. Ingber

  20. Example: • In class definition: friend complex operator +(complex c1, complex c2); • In class implementation: complex operator +(complex c1, complex c2) { complex temp; temp.real = c1.real + c2.real; temp.imag = c1.imag + c2.imag; return temp; } • In client program: complex cA, cB, cC; cC = cA+cB; cC = 54.3 + cB;//this is ok, when + is a friend function Engineering Problem Solving with C++, Second Edition. J. Ingber

  21. Class Declaration class complex { public: complex(); complex(double,double); friend ostream& operator <<(ostream&, complex); friend istream& operator >>(istream&, complex&); complex operator+(complex) const; complex operator-(complex) const; complex operator*(complex) const; complex operator/(complex) const; private: double real, imag; }; Engineering Problem Solving with C++, Second Edition. J. Ingber

  22. Implementation ostream& operator <<(ostream& os, complex r) { os << r.real << “ + “ << r.imag << ‘i’; return os; } istream& operator >> (istream& is, complex& r) { is >> r.real >> r.imag; return is; } Engineering Problem Solving with C++, Second Edition. J. Ingber

  23. Error Checking on input operator • If your input fails because of incorrect format, your function should mark the state of the istream as bad is.clear(ios::badbit | is.rdstate() ) • clear resets entire error state to zero • clear(ios::badbit) clears all and sets badbit • is.rdstate() returns the previous state of all bits • Statement sets the bit vector to the OR of badbit with previous state Engineering Problem Solving with C++, Second Edition. J. Ingber

  24. Top Level Functions • binary operators • top level function requires two arguments • unary operator • top level function requires one argument • Disadvantage: • Top level functions do not have access to private data members. Function must use accessor functions. Engineering Problem Solving with C++, Second Edition. J. Ingber

  25. Example of top level function • Function prototype in client program. complex operator +(complex c1, complex c2); • Implemention in client program. complex operator +(complex c1, complex c2) { return complex(c1.get_real() + c2.get_real(), c1.get_imag() + c2.get_imag()); } • Use in client program. complex cA, cB, cC; cC = cA + cB; cC = 54.3 + cA;//this is ok, when + is a top level //function Engineering Problem Solving with C++, Second Edition. J. Ingber

  26. factorial function binary trees recursion Engineering Problem Solving with C++, Second Edition. J. Ingber

  27. Recursion • Recursion is a powerful tool for solving certain classes of problems where: • the problem solution can be expressed in terms of the solution to a similar, yet smaller problem. • Redefinition of the problem continues in an iterative nature until: • a unique solution to a small version of the problem is found. • This unique solution is then used, in a reverse iterative nature until: • the solution to the original problem is returned. Engineering Problem Solving with C++, Second Edition. J. Ingber

  28. Recursion • Programming languages that support recursion allow functions to call themselves. • Each time a function calls itself, the function is making a recursive function call. • Each time a function calls itself recursively, information is pushed onto the runtime stack. • Each time a recursive function calls returns, information is popped off the stack. The return value, along with the information on the stack, is used to solve the next iteration of the problem Engineering Problem Solving with C++, Second Edition. J. Ingber

  29. Recursive Functions • A recursive function requires two blocks: • a block that defines a terminating condition, or return point, where a unique solution to a smaller version of the problem is returned. • a recursive block that reduces the problem solution to a similar but smaller version of the problem. Engineering Problem Solving with C++, Second Edition. J. Ingber

  30. Example: Recursive Definition of Factorial Function f(0) = 1 Unique solution. f(n) = n*f(n-1) Recursive definition. Thus, f(n) can be determined for all integer values of n>=0; Engineering Problem Solving with C++, Second Edition. J. Ingber

  31. Recursive Factorial Function long factorialR(int n) { /*Termination condition */ if(n==0) { return 1; //unique solution } /*Recursive block – reduce problem */ return n*factorialR(n-1); } Engineering Problem Solving with C++, Second Edition. J. Ingber

  32. Binary Tree Abstraction • A binary tree maintains two links between nodes. • The links are referred to as the leftchild and the rightchild. • The first node is called the root. • Each child(left and right) may serve as the root to a subtree. • A node without children is referred to as a leaf node. 32

  33. Diagram pointer to root * + 8 2 4 leaf node leaf node 33

  34. Implementation • A BinaryTree class with one attribute: a pointer (node*) to the root of a binary tree. 34

  35. BinaryTree class Methods: insert() delete() print() inOrder(), preOrder(), postOrder() • Implementation of insert: • Insert into empty BinaryTree establishes the root. • Each subsequent node is inserted in order: • values less than root are placed in the root’s left subtree • values greater than root are placed in the root’s right subtree 35

  36. preOrder Traverse display node visit left child visit right child *+248 36

  37. postOrder Traverse visit left child visit right child display node 24+8* 37

  38. inOrder Traverse Visit left child Display node Visit right child 2+4*8 38

  39. BinaryTree Class • Recursive Methods: • print(), insert(), clear() • Recursive methods are overloaded. • public version is non-recursive. • public version is called once. • public version calls private recursive version. • Recursive version calls itself.

  40. binary tree class templates Engineering Problem Solving with C++, Second Edition. J. Ingber

  41. class Templates • A binary tree is an ordered collection of nodes. • Each node has a data value, a right child and a left child. • The data type of the right and leftchild is node*. • The data type of the node valueis parameterized to form a class template. • The binary tree template also parameterizes the node type.. Engineering Problem Solving with C++, Second Edition. J. Ingber

  42. BinaryTree Declaration #include "node.h" template<typename T> class BinaryTree { public: BinaryTree():root(0){} //inline bool empty(){return root==0;} //inline void clear(){ if(root) {clear(root); root=0;} } //inline, non recursive void insert(const T& ); //… private: void clear(node<T>*); //recursive node<T>* root; //node is a class template }; 42

  43. Implementation of BinaryTree class //clear template<typename T> void BinaryTree<T>::clear(node<T> *pt) //method called from private clear() { if(pt){ clear(pt->getLeft()); clear(pt->getRight()); delete pt;} } //insert template<typename T> void BinaryTree<T>::insert(const T& value) { if(!root) root = new node<T> (value); //must qualify else root->insertValue(value); //member of node } 43

  44. insertValue: member of node class template<typename valType> void node<valType>::insertValue(const valType& val){ if(val < data){ if(!left) left=new node(val); //don’t need to quality else left->insertValue(val); } else { if(!right) right = new node(val); else right->insertValue(val); } } 44

  45. Sample Run int main() { BinaryTree<int> tree; if(tree.empty()) cout << "empty" << endl; tree.insert(10); if(tree.empty()) cout << "empty" << endl; else cout << "not empty\n"; tree.clear(); if(tree.empty()) cout << "empty" << endl; else cout << "not empty\n"; return 0; } output: empty not empty empty 45

  46. Suggestions for Writing templates • Get a non-template version working first. • Establish a good set of test cases. • Measure performance and tune. • Review implementation: • Which types should be parameterized? • Convert non-parameterized version into template. • Test template against established test cases. 46

  47. Inheritance Engineering Problem Solving with C++, Second Edition. J. Ingber

  48. Inheritance • Inheritance is a means by which one class acquires the properties--both attributes and methods--of another class. • When this occurs, the class being inherited from is called the base class. • The class that inherits is called the derived class. Engineering Problem Solving with C++, Second Edition. J. Ingber

  49. C++ and Public Inheritance • The private members of a base classare only accessible to the base class methods. • The public members of the base class, are accessible to the derived class and to clients of the derived class. • The protected members of the base class, are accessible to members of the derived class, but are not accessible to clients of the base class or clients of the derived class. Engineering Problem Solving with C++, Second Edition. J. Ingber

  50. UML Inheritance Diagram: • A Rectangle has a Point. • Square is a Rectangle. Engineering Problem Solving with C++, Second Edition. J. Ingber

More Related