210 likes | 312 Views
The C++ Programming Language. Week 6 & 7. Template. Original name – Parameterized Types Parameterized – Abstracted data type information from implementation
E N D
The C++ Programming Language Week 6 & 7
Template • Original name – Parameterized Types • Parameterized – Abstracted data type information from implementation • Type – For every class template or function template, there are different features and characters when bound to different data types, they act like a type • Template generate a function or class automatically, according to the value or type user specified • string, vector, list are all class templates, and we will implement our template in this lecture 面向对象程序设计
Root Piglet Eeyore Roo Left child Right child Chris Kanga Pooh Tigger Starting Point – the binary tree class • Operations that need to be provided • Insert, remove • Find, clear • Print (preorder, inorder, postorder) • Preorder: Piglet, Eeyore, Chris, Kanga, Roo, Pooh, Tigger (root, left, right) • Inorder: Chris, Eeyore, Kanga, Piglet, Pooh, Roo, Tigger (left, root, right) • Postorder: Chris, Kanga, Eeyore, Pooh, Tigger, Roo, Piglet left, right, root) 面向对象程序设计
The binary tree class • 2 classes • BinaryTree – storing only one pointer pointing to the root • BTNode – storing the value of node and links to left and right childs • We provide a non-template BTNode class declaration class string_BTNode { public: //… private: string m_szVal; int m_iCnt; string_BTNode* lchild; string_BTNode* rchild; }; 面向对象程序设计
Parameterized Types • Without Template, we have to implement multiple BTNode classes with different names and data types • For those insertion, deletion and traversing ops, their mechanism won’t change when node data type changes, thus are “type-independent” • We extract the “type-dependent” parts and parameterize them 面向对象程序设计
Parameterized Types (cont.) template < typename valtype > class BTNode; //forward declaration //… template < typename valtype > class BTNode //class definition { public: //… private: valtype m_Val; int m_iCnt; BTNode* lchild; BTNode* rchild; }; • The valtype in class template is used as a space reserver • It’s a type parameter that could replace any built-in type or user-defined type while running 面向对象程序设计
Parameterized Types (cont.) template < typename elemtype > class BinaryTree; //forward declaration template < typename valtype > class BTNode { public: //… private: //… friend class BinaryTree<valtype>; }; 面向对象程序设计
Parameterized Types (cont.) • To generate entity class from the class template, real types should be provided in the template parameter list(<>) which the type parameter would bind to • Usage BTNode< int > bti; BTNode< string > bts; • bti and bts are different objects from different classes 面向对象程序设计
Parameterized Types (cont.) • Definition of class BinaryTree template < typename elemtype > class BinaryTree { public: //… private: //… BTNode<elemtype> *m_root; }; • When we need to add template parameter list after the class template? • Except in the definition of class template and its member functions 面向对象程序设计
Define of class template template < typename elemtype > class BinaryTree { public: BinaryTree(); BinaryTree(const BinaryTree&); ~BinaryTree(); BinaryTree& operator=(const BinaryTree&); bool empty() { return m_root = = 0; } void insert(const elemtype& elem); void remove(const elemtype& elem); void clear(); private: BTNode<elemtype>*m_root; void copy(BTNode<elemtype>* dest, BTNode<elemtype>* src); //copy the src sub-tree to dest }; 面向对象程序设计
Define of class template (cont.) • Defining an inline function in the class template is the same like in a normal class (empty()) • But how to define it outside the class template? template < typename elemtype > inline BinaryTree<elemtype>::BinaryTree() : m_root( 0 ) {}; • template and template parameter list should be added • The reason why the second BinaryTree need not a template parameter list is that, after the class scope operator, everything could be regarded as in the scope of the class template 面向对象程序设计
Define of class template (cont.) template < typename elemtype > inline BinaryTree<elemtype>::BinaryTree(const BinaryTree& rhs) { copy(m_root, rhs.m_root); }; template < typename elemtype > inline BinaryTree<elemtype>::~BinaryTree() { clear(); }; template < typename elemtype > inline BinaryTree<elemtype>& BinaryTree<elemtype>::operator=(const BinaryTree& rhs) { if (this != &rhs) { clear(); copy(m_root, rhs.m_root); } return *this; }; 面向对象程序设计
Handle a type parameter • For a built-in and simple data type, there’s almost no difference between by-value and by-reference in efficiency • For a class or complex data type, by-reference is usually used for efficiency • But for type parameters of a template, we won’t know in advance the real type it represents • It is recommended declared them as const reference for the worst situation template < typename elemtype > BinaryTree<elemtype>::find(const elemtype& value) {}; 面向对象程序设计
Handle a type parameter (cont.) • Consider Initialization template < typename valtype > inline BTNode<valtype>:: BTNode(const valtype& val) :m_Val(val) { m_iCnt = 1; lchild = rchild = 0; }; template < typename valtype > inline BTNode<valtype>:: BTNode(const valtype& val) { m_Val = val; m_iCnt = 1; lchild = rchild = 0; }; Recommended //will call default constructor of Matrix //to m_Val before entering the body, //then the copy assignment operator //will call copy constructor of Matrix //to m_Val only once BTNode<int> btni(20); //No difference in performance BTNode<Matrix> btnm(mat8x8); //…? 面向对象程序设计
Implement the class template template < typename elemtype > inline void BinaryTree<elemtype>::insert(const elemtype& elem) { if (! m_root) m_root = new BTNode<elemtype>(elem); //配置一块空间,调用构造函数 else m_root->insert_value(elem); }; 面向对象程序设计
Implement the class template (cont.) template < typename valtype > void BTNode<valtype>::insert_value(const valtype& val) { if (val == m_Val) { m_iCnt++; return; } if (val < m_Val) if (! lchild) lchild = new BTNode(val); else lchild->insert_value(val); else if (! rchild) rchild = new BTNode(val); else rchild->insert_value(val); }; 面向对象程序设计
Implement the class template (cont.) template < typename elemtype > inline void BinaryTree<elemtype>::remove(const elemtype& elem) { if (! m_root) if (m_root->m_Val == elem) remove_root(); //will be handled specially else m_root->remove_value(elem, m_root); }; 面向对象程序设计
Implement the class template (cont.) template < typename valtype > void BTNode<valtype>::remove_value (const valtype& val, BTNode*& parent) { if (val < m_Val) if (! lchild) return; else lchild->remove_value(val, lchild) else if (val > m_Val) if (! rchild) return; else rchild->remove_value(val, rchild); else // val equals m_Val { if (rchild) { parent = rchild; if (lchild) if (! parent->lchild) parent->lchild = lchild; else BTNode<valtype>:: lchild_leaf(lchild, parent->lchild); } else parent = lchild; delete this; } } 面向对象程序设计
Implement the class template (cont.) template < typename elemtype > class BinaryTree { public: void clear() { if (m_root) { clear(m_root); m_root = 0; } } private: void clear(BTNode<elemtype>*); }; template < typename elemtype > void BinaryTree<elemtype>::clear(BTNode<elemtype>* pt) { if (pt) { clear(pt->lchild); clear(pt->rchild); delete pt; } }; 面向对象程序设计
Implement the class template (cont.) template < typename valtype > void BTNode<valtype>::preorder(BTNode* pt, ostream& os) const { if (pt) { display_val(pt, os); if (pt->lchild) preorder(pt->lchild, os); if (pt->rchild) preorder(pt->rchild, os); } }; template < typename valtype > void BTNode<valtype>::inorder(BTNode* pt, ostream& os) const { //…}; template < typename valtype > void BTNode<valtype>::postorder(BTNode* pt, ostream& os) const { //…}; 面向对象程序设计