Programsystemkonstruktion med C++: Övning 2 Karl Palmskog palmskog@kth.se september 2010
Specalfunktioner in classes Constructor constructors of a class initializes class members initial values can be given in the colon list or the code block default constructor is not used if the constructor is declared default constructor runs members constructor Copy Constructor takes an instance of the class as an argument Copy Constructor copies the members c l a s s V e h i c l e { p r i v a t e : i n t w e i g h t ; p u b l i c : V e h i c l e ( i n t w) : w e i g h t (w) { ;
Specalfunktioner in classes Destructor destructor takes no arguments and does not return anything default destructor is used if not defined runs members destructor Person : : Person ( ) { // f r e e up memory f o r a r r a y o f heap a l l o c a t e d s k i l l s d e l e t e [ ] s k i l l s ;
Specalfunktioner in classes Assignment operators and the Rule of Three the class instance variable is called assignment operator function operator= the default operator= copies the members heuristics: 1 if you need to define the destructor you need to define Copy Constructor operator= 2 if you need to define the Copy Constructor you need to define operator= 3 if you need to define the operator= you need to define the copy constructor destructor, copy and operator= are associated
Specalfunktioner in classes An inheritance hierarchy Animal string name Donkey Horse Mule
Specalfunktioner in classes Special functions and inheritance Objekt Konstruktor Destruktor Animal Animal Animal Donkey Animal Donkey Donkey Animal Horse Animal Horse Horse Animal Mule Animal Mule Donkey Horse Animal Animal Horse Donkey Mule Animal
Virtual Functions Virtual Functions non-virtual functions are selected statically at compile time, depending on the type of pointer or reference virtual functions are determined dynamically during execution based on the object s actual type #i n c l u d e <i o s t r e a m > using namespace s t d ; c l a s s A { p u b l i c : void f o o ( ) { cout << A : : f o o ( ) << e n d l ; v i r t u a l void bar ( ) { cout << A : : bar ( ) << e n d l ; ; c l a s s B : p u b l i c A { p u b l i c : void f o o ( ) { cout << B : : f o o ( ) << e n d l ; void bar ( ) { cout << B : : bar ( ) << e n d l ; ;
Virtual Functions Virtual functions in practice #i n c l u d e ab. h i n t main ( ) { B b ; B bptr = &b ; A aptr = bptr ; bptr >f o o ( ) ; bptr >bar ( ) ; aptr >f o o ( ) ; aptr >bar ( ) ; r e t u r n 0 ; $. / a. out B : : f o o ( ) B : : bar ( ) A : : f o o ( ) B : : bar ( )
Virtual Functions Implementation of virtual functions Mule v-table {... V-table *func1 *func2
Virtual Functions Virtual destructor What is the problem with this code? c l a s s A { p u b l i c : A( ) { s t d : : cout << A( ) << s t d : : e n d l ; ; c l a s s B : p u b l i c A { p u b l i c : B( ) { s t d : : cout << B( ) << s t d : : e n d l ; ; i n t main ( ) { A a = new A ( ) ; A b = new B ( ) ; d e l e t e a ; d e l e t e b ;
Virtual Functions Pure virtual function if a function is pure virtual, the classes are implemented by inheritance correspond to abstract methods in Java c l a s s A { p u b l i c : v i r t u a l i n t f o o ( ) = 0 ;... ; c l a s s B : p u b l i c A { p u b l i c : v i r t u a l i n t f o o ( ) {...... ;
templates (models) used to write type independednt code inheritance is an alternative to shared behaviors functions and classes parameterized on a given type compiler replaces occurrences of type parameters and create parameter free function/class
c l a s s Stack { p r i v a t e : s t a t i c const i n t STK SIZE = 1 0 0 ; i n t m stk [ STK SIZE ] ; i n t m top ; p u b l i c : Stack ( ) : m top ( 0 ) { bool isempty ( ) { r e t u r n ( m top == 0 ) ; bool i s F u l l ( ) { r e t u r n ( m top >= STK SIZE ) ; bool push ( i n t v a l ) { i f ( i s F u l l ( ) ) r e t u r n f a l s e ; m stk [ m top++] = v a l ; r e t u r n true ; bool pop ( i n t &v a l ) { i f ( isempty ( ) ) r e t u r n f a l s e ; v a l = m stk[ m top ] ; r e t u r n true ; ;
template <typename T> c l a s s Stack { p r i v a t e : s t a t i c const i n t STK SIZE = 1 0 0 ; T m stk [ STK SIZE ] ; i n t m top ; p u b l i c : Stack ( ) : m top ( 0 ) { bool isempty ( ) { r e t u r n ( m top == 0 ) ; bool i s F u l l ( ) { r e t u r n ( m top >= STK SIZE ) ; bool push ( const T &v a l ) { i f ( i s F u l l ( ) ) r e t u r n f a l s e ; m stk [ m top++] = v a l ; r e t u r n true ; bool pop (T &v a l ) { i f ( isempty ( ) ) r e t u r n f a l s e ; v a l = m stk[ m top ] ; r e t u r n true ; ;
Use of template class #i n c l u d e <i o s t r e a m > #i n c l u d e s t a c k. h i n t main ( ) { Stack<i n t > i s t k ; // s t a c k o f i n t Stack<double> f s t k ; // s t a c k o f d o u b l e s i s t k. push ( 4 7 1 1 ) ; i s t k. push ( 4 7. 1 1 ) ; f s t k. push ( 4 7. 1 1 ) ; f s t k. push ( 4 7 1 1 ) ; i n t i t o p ; i s t k. pop ( i t o p ) ; s t d : : cout << i t o p << s t d : : e n d l ; r e t u r n 0 ;
A template maxfunction Exam Assignment: write a template function max that returns the larger of two arguments. const & T max ( const T & x, const T & y ) { i f ( x < y ) { r e t u r n y ; e l s e { r e t u r n x ; Följdfrågor: what type parameter functionof the arguments is required? why is the return type of reference? why can not you give arguments of different types?
Meta Programming with templates #i n c l u d e <i o s t r e a m > template<i n t N> s t r u c t f a c t { enum { v a l u e = N f a c t <N 1>:: v a l u e ; ; template<> s t r u c t f a c t <0> { enum { v a l u e = 1 ; ; i n t main ( ) { s t d : : cout << f a c t <5>:: v a l u e << s t d : : e n d l ; r e t u r n 0 ;
Compilation of templatiserade classes and functions template classes/functions has to be defined before use usually occurs because both the declaration and definition of.h-file compiler need not be given the name of the class file support for separate production of the definition/declaration varies between compilers
Templatisering Vs. common super class common super class + code reuse + code reuse + static type control + flexibility + effective implementation - type control at run time - definition before use - overhead - slow compilation - large binary file