material for final exam ends advanced inheritance and templates other stuff 1 Kevin Sanft UCSB CS32 Summer 2010 Lecture 17 inheritance 2 Employee protected: int eID; string name; Address addr; SalaryEmployee void printPayStub() HourlyEmployee void printPayStub() inheritance: constructors constructors called starting from base class, then derived class recursive: if A is base class, B subclass of A, and C is subclass of B, then when creating an object of type C order of construction is A, then B, then C
never virtual
need complete information (need to know the exact type) to construct an object => not virtual 3 inheritance: constructors example 4 class MyBase { public: MyBase() { cout << "in MyBase() constructor\n"; } MyBase(int x) : data(x) { cout << "in MyBase(int) constructor\n"; } void setData(int theData) { data=theData; } protected: int data; };
class MyChild : public MyBase { public: MyChild() { cout << "in MyChild() constructor\n"; } MyChild(int x) { data=x; cout << "in MyChild(int) constructor\n"; } }; cout << "\ncreate MyBase base1:\n"; MyBase base1;
creat MyChild mc: in MyBase() constructor in MyChild() constructor
create MyBase* MyChild(): in MyBase() constructor in MyChild() constructor
create MyBase* MyChild(4): in MyBase(int) constructor in MyChild(int) constructor
inheritance: destructors ALWAYS virtual if not, a base type pointer that points to a derived class would call the base type destructor only potentially leaving orphaned memory that was allocated by the derived type destructors are called beginning with the most derived class, then the parent class, then grandparent, etc. up the hierarchy 6 inheritance: destructors example 7 class MyBase { public: ~MyBase() { cout << "in ~MyBase\n"; } void setData(int theData) { data=theData; } protected: int data; };
class MyChild : public MyBase { public: ~MyChild() { cout << "in ~MyChild\n"; } }; int main() { MyBase base1; MyChild mc;
cout << "\nending main\n"; } $ a.out deleting mbPtr in ~MyChild in ~MyBase
deleting mcPtr in ~MyChild in ~MyBase
ending main in ~MyChild in ~MyBase in ~MyBase
memory view of inheritance 9 Employee HourlyEmployee slicing! 10 class Parent { public: virtual int doSomething() { cout << "in Parent, returning x\n"; return x; }
private: int x; };
class Child : public Parent { public: int doSomething() { cout << "in Child, returning y\n"; return y; }
private: int y; }; void someImportantFunction(Parent p) { //...some stuff int important=p.doSomething(); //... } int main() { Child c; //... someImportantFunction(c); } $ a.out in Parent, returning x
remember: a pointer to a base type can point to its own type or a derived class (aka subclass, child class) cant hold or point to objects up the hierarchy (base/parent classes dont have all the pieces of the derived) a subclass has all members of the base class (though they wont be directly accessible if the base class members are private) for functions, compiler searches up hierarchy until finds it, if virtual inserts code to lookup at runtime 11 multiple inheritance is allowed in C++ if both have a speak() methodcompiler error if code tries to call myCatDogInstance.speak() can call myCatDogInstance.Dog::speak () (or myCatDogInstance.Cat::speak() can overwrite by defining CatDog::speak() { cout << meow-woof; } or upcast: static_cast<Dog>(myCatDogInstance).speak(); 12 Cat Dog CatDog adapted from Solter, Klepper Professional C++ . Wiley 2005. multiple inheritance 13 Cat Dog CatDog adapted from Solter, Klepper Professional C++ . Wiley 2005. Animal abstract classes Perhaps a pure virtual method virtual void speak() = 0; Then cant create instances of Animal, to create instances of subclass, must implement void speak() Cat::speak() { cout << meow; } Dog::speak() { cout << woof; }
15 Cat Dog Animal adapted from Solter, Klepper Professional C++ . Wiley 2005. why abstract classes? base classes that categorize concrete types: Animal no such thing as generic animal--dog, cat are subclasses (concrete types that are animals)
interfaces (the most common use of multiple inheritance) (contrast with Java) e.g. Clickable abstract class might only have an onClick pure virtual function any class that derives from Clickable (e.g. Button or Folder) must implement the onClick method 16 more on templates
17 std::string revisited C++ string class is a template class typedef basic_string<char> string;
http://www.cplusplus.com/reference/string/string/ 18 template function example 19 template<typename T> void shell_sort(std::vector<T>& v) { const std::size_t n=v.size(); for (int gap=n/2; 0<gap; gap/=2) { for (int i=gap; i<n; ++i) { for (int j=i-gap; 0<=j; j-=gap) { if (v[j+gap]<v[j]) { std::swap(v[j], v[j+gap]); } else break; } } } }
//(of course, you should just use //std::sort //#include <algorithm>) int main() { std::vector<int> intvec; intvec.push_back(7); intvec.push_back(2); intvec.push_back(3); intvec.push_back(6); intvec.push_back(11); intvec.push_back(9);
shell_sort<int>(intvec); typedef std::vector<int>::iterator it for (it i=intvec.begin(); i!=intvec.end(); ++i) { std::cout << *i << "\t"; } std::cout << "\n"; }
by default, compares elements using operator< you can pass it a function or function object to use instead 20 #include <algorithm> using namespace std; // sort (myvector.begin(), myvector.end()); //(12 26 32 33 45 53 71 80) sort (myvector.begin(), myvector.begin()+4); //(12 32 45 71)26 80 53 33 how does compiler ensure just one copy of each template instance? with GNU ld (linker) on ELF or MS Windows: compiler generates template instances in each translation unit, then linker collapses them together disadvantage: increased compilation time because template code may be compiled repeatedly 21 template class inheritance You can use inheritance with template classes template base class with template derived class template base class with non-template derived class non-template base class with template derived class warning! std::string and all stl containers DO NOT have virtual destuctors -- DO NOT create derived classes! someone asked me if you can create a subclass of std::vectortechnically, yes, but dont do it! vector * x = new Derived; delete x;//calls ~vector, not ~Derived and why would you want to? 22 template class inheritance example 23 template<typename _denseVectorT, typename _matrixT, typename _propensitiesFunctorT, typename _dependencyGraphT> class TauLeapExpAdaptive : public SSA_Direct<_denseVectorT, _matrixT, _propensitiesFunctorT, _dependencyGraphT> { typedef SSA_Direct<_denseVectorT, _matrixT, _propensitiesFunctorT, _dependencyGraphT> Base; //class declaration like you would expect... std::size_t in a lot of C++ code, youll see size_t size_t (size type) is the type returned by sizeof operator similar to unsigned int recall what an unsigned int is? size_t is guaranteed to be able to represent largest size your system can hold good practice to use size_t for sizes (in some cases, failure to do so can lead to portability issueson many, but not all, systems, size_t has the same range as unsigned int and unsigned long) memcpy example see: http://www.eetimes.com/discussion/programming-pointers/4026076/Why-size-t- matters 24 material for final ends here! 25 function pointers functions have an address in memory we can create a pointer to a function 26 //typedef FunctionReturnType(*NameOfFuncPtrType)(function params) typedef bool(*YesNoFunc)(int, int);
bool int_equal(int x, int y) { return (x==y); }
bool both_odd(int a, int b) { return (a % 2 == 1 && b % 2 == 1); }
void findMatches(int ary1[], int ary2[], int arySize, YesNoFunc compare) { for (int i=0; i!=arySize; ++i) { if (compare(ary1[i],ary2[i])) { cout << "match item " << i << ", value= "<<ary1[i]<<"\n"; } } } adapted from Solter, Klepper Professional C++ Wiley 2005. 27 int anArray[]={1, 3, 5, 7}; int anotherArray[]={7, 6, 5, 3};
using both_odd: match item 0, value= 1 match item 2, value= 5 match item 3, value= 7
function objects (aka functors) objects that can be called like a function sometimes called functions with state overloaded operator() 30 class MyFunctor {//GreaterThan public: //... bool operator()(int x, int y) { return (x>y); } }; function objects (aka functors) 31 vector<int> myvec; myvec.push_back(3); myvec.push_back(6); myvec.push_back(4); myvec.push_back(1);
other notes about templates if you dont provide the template arguments (e.g. min(arg1, arg2) instead of min<SomeType>(arg1, arg2)) when you declare an instance of template class or call a template function, the compiler will try to deduce the type based on the arguments:
good practice to explicitly state the template arguments 32 template<typename T> T min(T a, T b) { return a<b ? a:b; } //... int x=4, y=3; int z=min(x,y);//T is deduced to be int int z=min<int>(x,y); template specialization consider our Array template class from previous class
works for any type we can change the behavior of Array for a particular type using template specialization
33 template <typename T> class Array { T* data;//dynamically allocated array of type T objects int size; T getValue(int index);//could use operator[] //... }; template specialization suppose we want Array<bool> to manipulate an array of bits instead of bool types (to save memorya bool typically takes 1 byte=8 bits ) we declare a template specialization using the syntax:
34 template <typename T> class Array { T* data;//dynamically allocated array of type T objects int size; T getValue(int index);//could use operator[] //... }; template <> class Array<bool> { //...declarations specific to Array<bool> type //can provide different implementations, even different //functions... }; template partial specialization you can provide partial specialization of template classes that specializes one feature but not others probably most commonly used for pointer types the interface for pointers is different because you (usually) want to operate on whats being pointed to, not the pointer itself e.g. this wont work for a pointer template argument:
it would be nice if we could do the following for all pointer types:
35 if (x < y) { //... if (*x < *y) { //... template partial specialization e.g. this wont work for a pointer template argument:
it would be nice if we could do the following for all pointer types:
to declare a partial specialization for all pointer types:
36 if (x < y) { //... if (*x < *y) { //... template <typename T> class MyTemplateClass<T*> { //same stuff as before (or different, if you choose) //but with pointer dereference on all type T objects //... if (*x < *y) { //... //... func doSomething(T *val) {//... }; template template parameters say you want to make a stack template class and you want it to be a container adaptor has a template parameter for the underlying container (like the stl stack) e.g. make a stack, be able to use a vector OR a list as the underlying data structure (btw stl stack uses deque as default) 37 http://www.informit.com/articles/article.aspx?p=376878 template<typename T, typename Container> class Stack { //... };
Stack<int, vector<int> > myStack1; Stack<int, vector<double> > myStack2;//allowed but bad! template template parameters above is basically how stl stack is implemented (but with deque instead of vector) could provide additional safety with template template parameters: 38 http://www.informit.com/articles/article.aspx?p=376878 template<typename T, typename Container = vector<T> > class Stack { //... };
Stack<int> myStack1;//Container is vector<int> Stack<int, vector<double> > myStack2;//see, still dangerous template <typename T, template <typename> class Container> class Stack { //... private: Cont<T> data; }; inheritance: copy ctor, operator= we know the copy constructor and assignment operator are important if declaring dynamic memory in a class in a subclass, you usually want to be sure to call the parent copy constructor instead of the parent default constructor within the function similarly, you usually want to call the parent assignment operator within a derived class operator= 40 inheritance: copy ctor, operator= 41 class Base { public: Base(); Base(const Base&); Base& operator=(const Base&); };
class Sub : public Base { public: Sub(); Sub(const Sub&); Sub& operator=(const Base&); };
Sub& Sub::operator=(const Sub& other) { if (&other==this) return *this; Base::operator=(other);//Call Base's assignment op //...do Sub-specific assignments } homework 4 due Thurs. (8/19) at beginning of class (hard copy) extra credit homework 5 posted; due Friday 8/27 (day after final) 11:59pm (using turnin commandfollow instructions) contact instructor with questions homework 5 will not be accepted after 11:59pm on 8/27 (--no 24-hour 25%-penalty grace period)
additional office hour? Friday morning? 11:00? 44 course overview and remaining schedule architecture basics, OS basics, linux, shell scripts, compilation, libraries C++, classes and objects, constructors, destructors, operator overloading, static members, dynamic memory, program layout in memory, namespaces, casts, testing and exceptions, hash tables inheritance and polymorphism, abstract classes, template classes/functions (generics), standard template library: containers, iterators, algorithms 45 week date topic 9 8/17 class (today) more inheritance/templates 8/18 lab continue lab 8: Page Rank project 8/19 class review homework 4 fun stuff not on final exam (suggestions?)? 10 8/24 class final review 8/25 lab extra credit lab 8/26 class final exam course evals Course: CS 32 Instructor: Kevin Sanft 46