1 / 22

Templates

Templates. Class Stack Generic Stack Potential Problems Class string Class Pear. class Stack{ public: Stack(){ data = new int[10]; top=-1;} ~Stack(){ delete [] data;} Stack& push(int e){ data[++top]=e;return *this;} Stack& pop(int &e){

gage-barnes
Download Presentation

Templates

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. Templates • Class Stack • Generic Stack • Potential Problems • Class string • Class Pear

  2. class Stack{ public: Stack(){ data = new int[10]; top=-1;} ~Stack(){ delete [] data;} Stack& push(int e){ data[++top]=e;return *this;} Stack& pop(int &e){ e = data[top--];return *this;} void print() const{ for(int i=top;i>=0; i--) cout<<data[i]<<' '; } private: int top int *data; }; Class Stack void main(){ Stack s; s.push(1).push(2); s.push(3).push(4); s.print(); //4 3 2 1 int x = 0; s.pop(x); cout<<"x = "<<x; //x = 4 } *(See stack.cpp.txt)

  3. Problems with This Class • Some can be fixed • Size of stack restricted to 10 (maximum) • No checks for pushing full stack or popping empty stack • Some cannot be fixed • What if we want to add a stack of real numbers (double or float)? • What if we want to have a stack of character strings?

  4. Solution • Do not want to write a new version of Stack of each potential data type • int, float, double, char, string • Instead, we need to identify a generic framework for a Stack that we can then use to build • Stack of integers • Stack of characters • Stack of doubles

  5. Templates • Class templates also called parameterized types • Require one or more parameters to specify the generic class type • Need to make slight changes to syntax in • Class declaration • Implementation of the data structure • Example: see GenStack.cpp.txt

  6. Changes in Class Declaration template <class S> class GenStack{ public: GenStack(){ data = new S[10]; top=-1;} ~GenStack(){ delete [] data;} GenStack& push(S); GenStack& pop(S &); void print() const; private: int top; S *data; };

  7. Changes in Member Functions template <class S> GenStack<S>& GenStack<S>::push(S e){ data[++top] = e; return *this;} template <class S> GenStack<S>& GenStack<S>::pop(S &e){ e = data[top--]; return *this;} template <class S> void GenStack<S>::print() const{ cout<<'['; for(int i=top; i>=0; i--) cout<<data[i]<<' '; cout<<']'<<endl; }

  8. Changes for Class Users void main(){ GenStack<int> s1; s1.push(1).push(2).push(3).print(); //[3 2 1 ] GenStack<double> s2; s2.push(5.5).push(6.6).push(7.7).print(); //[7.7 6.6 5.5 ] GenStack<char> s3; s3.push('a').push('b').push('c').print(); //[c b a ] }

  9. typename • You can use either “<class T>” or “<typename T>” when using templates

  10. Still Have Problems • Works for primitive data types, but not for non-primitive data types, unless • The non-primitive data type has a constructor that takes no arguments • The non-primitive data type supports the assignment (=) operator • The non-primitive data type supports the copy constructor

  11. Example Problem int main(){ GenStack<char *> s; char *str1 = new char[10]; strcpy(str1,"string1"); char *str2 = new char[10]; strcpy(str2,"string2"); char *str3 = new char[10]; strcpy(str3,"string3"); s.push(str1).push(str2).push(str3); s.print(); //[string3 string2 string1 ] delete str1; char *str4 = new char[10]; strcpy(str4,"ABCxyz"); s.print(); //[string3 string2 ABCxyz ] return 0; } //See problem.cpp

  12. GenStack<char*> Problems • Push: data[++top] = e; • Pop: e = data[top--]; • This is not how you deal with “char*” data • Use strcpy instead • Must allocate space to store copy of string • Data type S must have the operations defined for it that you use with the class • The assignment operator for strings is not "="

  13. Solution • Use Class string • C++ provides a pre-defined class called “string” • Has a constructor with no arguments • Has an assignment operator • Has a copy constructor • So we can use this in our program instead of the C-type character arrays

  14. String Solution #include <string> using std::string; int main(){ GenStack<string> s; { string *str1 = new string("string1"); string str2("string2"); string str3; str3 = "string3"; s.push(*str1).push(str2).push(str3); s.print(); //[string3 string2 string1 ] delete str1; string *str4 = new string("string4"); } s.print(); //[string3 string2 string1 ] return 0; } //See classString.cpp

  15. Works for Class Pear void main(){ GenStack<Pear> s; Pear *p = new Pear; s.push(*p); p = new Pear(2); s.push(*p); p = new Pear(3,3); s.push(*p); s.print(); //[(3,3) (2,0) (0,0) ] delete p; s.print(); //[(3,3) (2,0) (0,0) ] }

  16. Class Pear Refresher class Pear { int a,b; public: /*constructor with no arguments*/ Pear(){ a=0; b=0; } Pear(int x){a=x; b=0;} Pear(int x, int y){a=x; b=y;} /*copy constructor*/ Pear(const Pear &p){ a=p.a; b=p.b; }

  17. Class Pear Refresher /*assignment operator*/ const Pear& operator=(const Pear &p){ a=p.a; b=p.b; return *this; } void setA(int x){a=x;} void setB(int x){b=x;} int getA(){return a;} int getB(){return b;} friend ostream & operator<<(ostream & banana, const Pear & p){ banana<<'('<<p.a<<','<<p.b<<')'; return banana;} };

  18. Why Class Pear Works • Constructor with no arguments: GenStack(){ data = new S[10]; top=-1; } • The GenStack constructor makes an array of 10 objects calling a constructor which has no arguments • Class Pear has a constructor with no arguments

  19. Why Class Pear Works • Assignment operator: • Push: data[++top] = e; • Pop: e = data[top--] • Since a memberwise assignment operator is defined automatically, this works for classes with non-dynamic data types (data members that are not pointers) • For dynamic data types, such as a binary tree, the appropriate assignment operator (& copy constructor) must be created by the programmer

  20. Why Class Pear Works • Copy Constructor • GenStack<S>& GenStack<S>::push(S e) • In this function, the copy constructor is called (pass by value) • GenStack<S>& GenStack<S>::pop(S &e) • In this function, the copy constructor is not called (pass by reference)

  21. Essential Member Functions • Constructor with no arguments Pear(){a=0; b=0;} • Assignment operator Pear(const Pear &p){ a=p.a; b=p.b;} • Copy constructor const Pear& operator=(const Pear &p){ a=p.a; b=p.b; return *this;} (See pear.cpp)

  22. Class Exercise 1 • What’s the output of this program? • exercise1.txt

More Related