Object-Oriented Programming in C++ CS20006: Software Engineering

Lecture 02Prof. Partha Pratim Das

Jan 2013

Object-Oriented Modeling & Programming

Jan 2013 OOP in C++ 2

       Procedural Enhancements in C++ over C Classes Overloading Inheritance Type Casting Exceptions Templates
Jan 2013 OOP in C++ 3

Object Oriented Programming in C++ PROCEDURAL ENHANCEMENTS IN C++ Jan 2013 OOP in C++ 4 .

TOPICS       Const-ness Reference Data Type Inline Functions Default Function Parameters Function Overloading & Resolution Dynamic Memory Allocation Jan 2013 OOP in C++ 5 .

 Pointer to a non-constant object can not point to a const object. constant pointer to an object. double * const *pConstantPointer. const double * pConstantObject. double *p = &d.6. //error  Pointer to a constant object vs. Jan 2013 OOP in C++ 6 .  Example: const int capacity = 512.  Any attempt to write a const object is an error  Const object must be initialized.const Quantifier  const qualifier transforms an object into a constant. const double d = 5.

int& i = j.References  A reference is an additional name / alias / synonym for an existing variable  Declaration of a Reference <type> & <name> = <existing variable>. Jan 2013 OOP in C++ 7 .  Examples of Declaration int j = 5.

References  Wrong declarations  int& i. // may be declared as const reference  int& i = j+k. // must be initialized  int& j = 5. // may be declared as a const reference  Often used as function parameters :  called function can change actual argument  faster than call-by-value for large objects Jan 2013 OOP in C++ 8 .

.References Do not . Jan 2013 OOP in C++ 9 .  Cannot change the referent of the reference (Reference can not be assigned)  Cannot take the address of the reference  Cannot compare two references  Cannot do arithmetic on references  Cannot point to a reference  All operations on a reference actually work on the referent.  Cannot have an array of references  No operator other than initialization are valid on a reference.

Returning a Reference Returning a reference  return value is not copied back  may be faster than returning a value  calling function can change returned object  cannot be used with local variables Jan 2013 OOP in C++ 10 .

y = 7500.> int& max(int& i.Returning a Reference #include <iostream. cout << " y = " << y. return 0. z. } Jan 2013 OOP in C++ 11 . cout << " z = " << z << "\n".h. y) . // y is now 1 cout << "x = " << x. y) = 1 . z = max(x. } int main(int. int& j) { if (i > j) return i. char *[]) { int x = 42. else return j. // z is now 7500 max(x.

Pointers vs. its referent is fixed. Pointer does. Jan 2013 OOP in C++ 12 .  References make code faster since. unlike pointers.  Pointers can point to different variables at different times whereas for a reference. checks for NULL are not required.  Reference “refers” to an address but does not store that address. There is nothing defined as NULL Reference. References  Pointers can point to NULL whereas References cannot.

 Type checking during parameter passing is not done  Code size tend to increase  Typical Use:  Small code re-use Jan 2013 OOP in C++ 13 .  Advantages:  Speed-wise efficient  Disadvantages:  Parameter passing mechanism is not robust and frequently leads to errors.Macros  Macros are expanded at the places of their calls.

Inline Functions  Inline functions act like functions         Jan 2013 They Type They They can be class members checking is performed can be overloaded obey normal parameter passing rules  But they are implemented like macros Code is substituted inline.cxx files OOP in C++ 14 . not in .c/.h files. not called Use is faster than calling a function Use may take more space They are defined in .

Jan 2013 OOP in C++ 15 .  May cause unexpected behavior if compiler does not chose to make the function inline. an inline function must be defined in every text file where it is called.  A recursive or a large function may not be inline.  Unlike a non-inline function.Inline Notes  inline specification is only a recommendation.  Inline functions must not have two different definitions.

 Default parameters should be supplied only in a header file and not in the definition of a function.  Default arguments cannot be re-defined. Jan 2013 OOP in C++ 16 .  Default arguments may be expressions also.  Default arguments can be supplied to one or more parameters.Default Function Arguments  Default arguments are appropriate argument value of a parameter for a majority of cases.  All parameters to the right of a parameter with default argument must have default arguments.

char ch). char = „a‟).0. the following are correct. char *= NULL). float. // Error // OK // Error – Redefinition Assume that ff. float = 0. //OK ff(int i = 0.h> ff(int i. char *). float f = 0. Void ff (int.0. char ch = „a‟). //OK Jan 2013 OOP in C++ 17 . #include <ff. char *=NULL). float = 0.h” ff(int i. ff(int. Void ff2(int float = 1. float f = 0. //Error However. float f.0.h contains the following declaration Wrong example: #include “ff. Void ff2(int.Default Arguments: Example  Following are some examples of functions with default arguments. char ch).

Function Overloading  The same function name may be used in several definitions.  Function selection based on number and types of the actual parameters at the places of invocation.  Function selection (Overload Resolution) is performed by the compiler  Two functions having the same signature but different return types will result in a compilation error due to “attempt to redeclare”.  Overloading allows static polymorphism Jan 2013 OOP in C++ 18 .  Functions with the same name must have different number of formal parameters and/or different types of formal parameters.

 Select the best viable function through (Order is important)     Jan 2013 Exact Match Promotion Standard type conversion User defined type conversion OOP in C++ 19 .Overload Resolution  Steps to resolve overloaded functions with one parameter  Identify the set of candidate functions and the set of viable functions.

char *). void f(int). void f(char. 2. 4. void f().6) Candidate function: 2 & 3 Best function: 3 Jan 2013 OOP in C++ 20 . void f(double.4). f(5.Overload Resolution  Steps to resolve overloaded functions with one parameter  Example: 1. double = 3. 3.

Exact Match  lvalue-to-rvalue conversion  Most common  Array-to-pointer conversion Definitions: int ar[10]. fp). void f(int *a). Call: f(ar)  Function-to-pointer conversion Definitions: int (*fp) (int). void f(int x. Call: f(5. int g(int). g)  Qualification conversion  Converting pointer (only) to const pointer. Jan 2013 OOP in C++ 21 .

float to double  enum to int/long/unsigned int/…  bool to int  Examples of Standard Conversion  integral conversion  floating point conversion  floating point – Integral conversion The above 3 may be dangerous!  pointer conversion  bool conversion Jan 2013 OOP in C++ 22 .Promotion & Conversion  Examples of Promotion  char to int.

void print(char *). int main() { f(a1). void set (const char *). char *f(unsigned int). Promotion enum e1 { a1. c1 }. Conversion Sequence int arr[3]. char *f(int). int main() { print (0). //Which f? 3. //Which f? } 2. void set (int *). Standard Conversion void print(int). //Which print? set (0). void putValues(const int *). int main() { putValues(arr). } Jan 2013 //Which set? OOP in C++ 23 .Examples of Resolution 1. c2 = 0x80000000000 }. b2. enum e2 { a2. b1. } f(a2).

int *pI = new int.  new is polymorphic  new does more than malloc! Jan 2013 OOP in C++ 24 . the new and delete operators provide built-in language support for dynamic memory allocation and deallocation. const int *pI = new const int(100). delete pI. delete [] pArr. Arrays generally cannot be initialized. Array of constant cannot be created. //new initializes!! int *pArr = new int[4*num]. int *pI = new int(102).new/delete operators  In C++.

Jan 2013 OOP in C++ 25 .  Matching operators  malloc-free  new-delete  new[] – delete []  It is a good idea to use only new and delete in a C++ program.  Do not delete the space created by malloc  Results of the above two operations is memory corruption.new/delete & malloc/free  All C++ implementations also permit use of malloc and free routines.  Do not free the space created by new.

Object Oriented Programming in C++ CLASS Jan 2013 OOP in C++ 26 .

TOPICS      Class Members Constructor & Destructor Friends Static Members Struct & Union Jan 2013 OOP in C++ 27 .

Jan 2013 OOP in C++ 28 . class is the only way to implement user defined data types. classes in C++ are responsible to offer needed data abstraction/encapsulation of Object Oriented Programming.Class  C++ Class is an implementation of “type”  In C++.  A C++ class contains data members/attributes to specify the state and operations/methods to specify the behavior.  C++ Classes also provide means (through access specifier) to enforce data hiding that separates implementation from interface.  Thus.

  private – these members are accessible inside the definition of the class. Jan 2013 OOP in C++ 29 .  The implicit this pointer holds the address of any object.  this pointer is implicitly passed to methods.” operator on the object.Class  A Class is defined by “class” keyword.  Members can be accesses by “.  Objects/instances of classes are to be created statically or dynamically.  Each member in a class has an access specifier. public – these members are accessible everywhere.

} char *getName ( ) { return name. Employee *e2. e1. *name. e2>setSalary(29100).setSalary(29100). } void setSalary (float y) { salary = y.A Simple Class class Employee { public: void setName (const char *x) { name = strdup(x). float salary. // Error e2.setName(“Amit”). } private: char }. } float getSalary ( ) { return salary. e2 = new Employee. int main () { Employee e1. e2->name = strdup(“Ashis"). } Whose name? void setName (const char *x) { this->name = strdup(x). } OOP in C++ 30 Jan 2013 . } Re-look at void setName (const char *x) { name = strdup(x).

x->prev = this. } DoublyLinkedNode::append(DoublyLinkedNode *x) { next = x. } Jan 2013 OOP in C++ 31 .More on this  Type of this  Necessity of this to the programmer  X * const  Distinguishing data member from non-member variable  Explicit Use class DoublyLinkedNode { DoublyLinkedNode *prev. *next. int data. public: void append(DoublyLinkedNode *x).

 allow the class to initialise the state of an object Jan 2013 OOP in C++ 32 .Constructor Functions  Constructor functions:  are member functions with the same name as the class  are automatically called when an object is created. just after memory allocation  In case of auto/static variables.  Objects can be created in the Free store with a pointer storing the address. objects are created in the stack/static Store when their definition is encountered.

Constructor Functions  Constructor functions:  Constructors also allocate additional memory space from the Free store (if) required for the object. Jan 2013 OOP in C++ 33 .  If users do not define any constructor then the compiler provides a default constructor.  must not have any return type even void  Default constructors are those constructors which either do not have an argument or have default arguments for all parameters.

Jan 2013 OOP in C++ 34 .  X *pX = new X().  If there is at least one definition of constructor but no default constructor then the following statements are incorrect  X a.Additional Constructor Functions  Constructor function can be overloaded  Constructor functions can be directly called to create anonymous objects  Calling a constructor from a constructor does not have the desired effect.

just before memory is freed   For auto variables when the variable goes out of scope For objects created in the Free store.Destructor Functions  Destructor function:  is a member function named “~ <class-name>” String ( ) ) (e. Jan 2013 OOP in C++ 35 .g. ~  is automatically called when an object is destroyed. destructor is called after “delete” or “delete[]” is explicitly invoked by the programmer.  must not have any argument or return value  If destructor is not called then there could be memory leaks for objects which calls “new” in the constructor.

Jan 2013 OOP in C++ 36 .  Copy constructor of class X takes an argument of type X &. an infinite loop results.  If the type of argument is X in stead of X&.Copy Constructor  Copy constructor is a special constructor which is used to initialize an object with another object of the same type.

Jan 2013 OOP in C++ 37 .Copy Constructor  Situations where copy constructor is used:  Actual parameter passing in call-by-value  Return Value passing  Initializing an object with an object of the same type as shown in the following example.  The compiler provides a default implementation of the copy constructor.

private: char *data. String(const String&). ~ String(). int length(). // Copy Constructor String(const char *). int len. void print(). } Jan 2013 OOP in C++ 38 . int read().A Sample Class : String class String { public: String().

String s2(str). String s3(s2).Class String::Constructor & Destructor String::String() { int main() { String s1. strcpy(data. delete s5. String s5 = new String(). s). //default constructor String s11(). //Copy Constructor String s4 = new String(“one”). } OOP in C++ 39 . String::String(const char *s) { data = new char[strlen(s)+1]. } void ~String() { if (data != NULL) delete [] data. delete s4. } char str[6]. “Hello”). len = strlen(s). //Error String s1(“test”). } Jan 2013 data = NULL. len = 0. strcpy(str.

Arrays  Using Default constructor while creating an array of objects  String arrayOfString[100]. String(“def”) }. new String(“def”) }.  String arrayOfString[2] = { String(“abc”).  Using different constructor for creating array objects dynamically. OOP in C++ 40 . // 100 objects created using the default constructor  Using specialized constructor while creating an array of objects.  Jan 2013 String *pArrayOfString[2] = { new String(“abc”).

 No space is required per object for storing function pointers for the methods declared in the class. an object of a class must have enough space to store all members of that class.  Methods on objects are translated by the compiler to C-like function calls by passing this pointer.Object Layout  Simplistically. A String Object data len H e l l o \n Jan 2013 OOP in C++ 41 .

 Employee class may have a member “name” whose type is String. Jan 2013 OOP in C++ 42 .  When an Employee object is initialized then name must also be initialized.Members as Objects  Sometimes a class may have a data attribute which is an object of a class.

after a constructor‟s parameters and before the constructor definition where each list item is a named member object followed by its initializer value in parenthesis  Initializer lists are required for a member object that must be passed initial arguments for construction  Initializer lists are required for const members and reference members Jan 2013 OOP in C++ 43 .Members as Objects  Initialization of member objects can be arranged through the use of initializer lists  Initializer lists appear as a comma separated list    following a colon.

 Composition through objects are preferred over Composition through pointers  Saves time and life cycle management  Not possible in a number of situations   Contained object is shared by many containers. Contained object may not always be present.  Methods should not return non-const reference or pointer to less accessible data  Defeats basic data hiding philosophy. Jan 2013 OOP in C++ 44 .Class Member: Notes  It is always a good idea to define data members as “private”.  May also lead to stunning consequences.

//accessing members OK ipriv += temp.Const Member Functions  Constant Member Functions are not allowed to change the state of the object on which they are invoked. public: int ipub. int X::f() const { int temp. Type of this pointer passed to a const function is const X* const this class X { private: int ipriv. temp = ipriv + ipub. // cannot modify any member ipub -= temp. const must also be present at the definition. int f() const. // cannot modify any member }    Jan 2013 OOP in C++ 45 . }. Const Functions are declared with keyword const following member function parameter list.

Friend Functions Friend functions  are declared in one or more classes  have access to the private members of those classes  are distinguished from members with the keyword friend  are not called with an invoking object of those classes Jan 2013 OOP in C++ 46 .

left->data). strcat(both. right->data). left). friend String concat(char *. } String concat(String *left. String *). String *right) { String both[strlen(left) + right->len + 1]. char *).data. String(const char *).data. return both. right-> data) . String *right) { String both[left->len + right->len + 1]. data = new char[len+1]. int len. return both. strcpy(both. data[len] = „\0‟. strcpy(both. String *) friend String concat(String *. } .data. } String concat(char *left.data. friend String concat(String *. String::String(int len) { this->len = len. private : char *data. String(int len). } Jan 2013 OOP in C++ 47 . strcat(both.Friend Functions: Example class String { public : String().

int n. friend Vector prod(Matrix *pM. Vector *pV). i++) for (j = 0. }. j++) { v[i] += pm->elements[i][j]* pV->elements[i]. int m. } } Jan 2013 OOP in C++ 48 . int n) . private : int elements[10][10]. j < pM->n. }. class Matrix { public : void Matrix(int m. // Forward declaration to make // declaration of crossprod legal class Vector { public : void Vector(int n) .Friends of More Than One class class Matrix. Vector *pV). int elements[10] . for (i = 0. i < pM->m. n. Vector prod(Matrix *pM. Vector *pV) { int V(pM->m). friend Vector prod(Matrix *pM.

Friends tend to break data hiding. int elements[10]. A class may be declared as a friend implying all member functions of that class are friends. } .Friend Members & Class   Member of a different class may be a friend function. Friend-ship is neither commutative nor transitive. int m. friend Vector Vector::prod(Matrix *pM). n. It is best to avoid friend in an ideal OO Design. class Matrix { public: void Matrix(int m. Vector prod(Matrix *pM). class Vector { public: void Vector(int n). int n). } . class Matrix. private: int elements[10][10]. int n.    Jan 2013 OOP in C++ 49 .

// This is a declaration X() { count++.count). a. b. X::count. //Definition & Initialization int main() { X a. c. c.Static Data  A static data member is shared by all the objects of a class. printf(“%d %d %d %d\n”.  Static data member may be public or private.count.  Static data member must be initialized in a source file.count. b. } } X::count = 0.  It can be accessed  with the class-name followed by the scope resolution operator “::” as a member of any object of the class class X { public: static int count. } The output will be 3 3 3 3  Jan 2013 OOP in C++ 50 .

next = NULL.Static Data: A List class ListNode { public: static ListNode *first. } printf(“\n”). x = x->next. int data. } int main() { ListNode x(5). ListNode x(8). x->data). x. ListNode x(7). print(). else { next = first. while (x != NULL) { printf(“%d “. if (first == NULL) first = this. } } Jan 2013 void ListNode::print() { ListNode *x. first = this. x = ListNode::first. } The output will be 8 7 5 OOP in C++ 51 . private: ListNode *next. public: ListNode(int x).print(). } List Node *ListNode::first = NULL. ListNode::ListNode(int x) { data = x.

Static Member Functions  Static member functions  May be invoked  with the class-name::  class_name::static_function (args)  as part of any objects interface  any_object.  this pointer is not passed to a static function  must not refer to non-static members of its “invoking object”  Philosophy of static members.static_function (args). Jan 2013 OOP in C++ 52 .

cxx #include “X. } inline String X::g() { // do some operation on s return s.hxx” void X::f() { X::g().cxx #include “X.hxx Class X { public: static void f(). } The above code will not fail. private: static String s. The code in the following may fail however. X1. } Data members are guaranteed to be initialized before any noninline function is called. static String g().hxx” int main() { X::g(). OOP in C++ 53 Jan 2013 . } X.Static Members in Inline Functions  Not Safe X.

Object Oriented Programming in C++ OPERATOR OVERLOADING Jan 2013 OOP in C++ 54 .

Overloading Operators  Semantics of an operator is represented by a function named operator op. )  These functions can either be implemented as global friend functions and/or methods. .. [ ]. Jan 2013 OOP in C++ 55 . where op is an operator symbol (+. etc.*.

operator+(s2) if there is a function named “operator+” defined in the class String.  “s1+s2” is also equivalent to operator+(s1. typically such global functions are friends to the class String.  “s1 + s2” denote concatenation of strings s1 and s2. s2) if a global function named “operator+” is properly defined.Overloading Operators  Example  Let „+‟ denote concatenation for Strings.  An expression of the form “s1+s2” is converted to s1. Jan 2013 OOP in C++ 56 .

String (char *data).Example of overloading operator + / * string . strcpy(save. } private : char *data. String operator+(char * text) { char *save = new char[len+1]. data = new char[len +strlen(text) + 1]. len = 0. String () { data = NULL. class String { public : String opertator + (char *text) . save). int len. String opertator + (String &s1) . text). strcpy(data. }. delete[]save. data). stcat(data. return (*this). } Jan 2013 OOP in C++ 57 .h * / const int max_string_length = 128 .

Overloading Assignment Operator
String & String: :operator=( char *rhs) { data = new char [strlen(rhs) + 1]; strcpy ( data, rhs); return *this ; } String String: :operator=( String &rhs) { data = new char [rhs.len + 1]; strcpy ( data, rhs.data); return *this ; }

Bug:  Memory Leak as previous data of this is not deleted.
. . .

Bug:  The following assignment cannot be made
 String x(“abc”), y(“def”), z(“ghi”);  x = y = z;  (x.operator=((y).operator=(z) ));

Solution  Change the return type to String &
OOP in C++ 58

Jan 2013

Overloading Assignment Operator
String & String: :operator (String &rhs) { delete [] data; data = new char [rhs.len + 1]; strcpy ( data, rhs.data); return *this ; }

Bug:  Self Assignment will cause problem Solution:  Check the following condition and return if false. if (this != rhs) .
Jan 2013 OOP in C++ 59

Reference & Overloading
 Suppose that we have a class Integer which has a private data member as int. The following function is declared as a friend of Integer.
Integer & operator*(Integer &lhs, Integer &rhs) { Integer result = lhs.data * rhd.data; return result; } Integer & operator*(Integer &lhs, Integer &rhs) { Integer *result = new Integer( lhs.data * rhd.data); return *result; }

Problem: Returning reference to a local object. The code fails.
Jan 2013

Who deletes? The caller. What about the following use? Integer a(1), b(2), c(3), d(3); Integer e = a*b*c*d;

OOP in C++

In absence of user defined assignment operator function.  If there is a need to define a copy constructor then there must be a need to overload assignment operator and vice-versa.  System defined function makes a shallow copy. Jan 2013 OOP in C++ 61 .More On “=” Operator Overloading  There is a system defined implementation of assignment operator. systems‟ function is used. assignment operator may have to be overloaded.  Some times shallow copying may be dangerous  If the constructor uses new.

 Prototype for post increment function:  void operator ++ (int a).  Exceptions:  post increment and post decrement operators. the name of the function is the the same. Jan 2013 OOP in C++ 62 .  As there are two operators with the same symbol “++”.Overloading Unary Operators  Typically methods implementing unary operators will not have any argument.  Prototype for pre increment function:  void operator ++ ( ).

 Precedence or arity of an operator cannot be changed by overloading an operator.Operator Overloading Facts  Some operators can not be implemented as global(friend) functions. sizeof() etc.  =.. comma operator should not be overloaded.  Conditional Operators like &&. ||..  Some Operators cannot be overloaded  ::..*. Jan 2013 OOP in C++ 63 .?:. [] etc.

Friends Vs Methods  Members are better in terms of restriction of scope which results in efficient searching for best function to resolve overloading.  String s1 = “abc” + s2.  Members will not help if the left hand side of the operator is not of the class type. we need friend due to the reason stated above. Jan 2013 OOP in C++ 64 . // may be wrong  In case of overloading stream operators.  Resolving in case of a conflict between friend and method.

Returning const from a function  Consider the following definition const Rational & operator * (const Rational & lhs. b. c. Jan 2013 OOP in C++ 65 . the following is valid. const Rational & rhs).  If the function returns a non-const.  Retuning const ensures that overloaded “*” is compatible with the same operator on built-in types. Rational a. (a * b) = c.

// Error!!! Jan 2013 OOP in C++ 66 . } private: char * data. cout << s[0].Overloading using const Class String { public: char & operator [ ] (int pos) { return data[pos]. …… } String s1 = “Hello”. // fine s[0] = „x‟. } const char & operator [ ] (int pos) { return data[pos]. // fine const String cs = “World”. cout << s[0]. // fine s[0] = „x‟.

Conceptual const  What should a constant member function preserve?  Bit-wise const-ness  Conceptual const-ness  Bit-wise const member functions may become unsafe. Jan 2013 OOP in C++ 67 .  Conceptual const member function may need to change some bits of the object  mutable keyword.Bit-wise const vs.

Object-Oriented Programming in C++ INHERITANCE Jan 2013 OOP in C++ 68 .

Topics  Fundamentals of Inheritance  protected Access Specifier  Initialization  Virtual Functions Jan 2013 OOP in C++ 69 .

Reusability  Reuse an already tried and tested code  Advantages:  Reduces cost & development time.  Improves quality  C Style Code Reuse  Library Function  Disadvantage: Reuse cannot be customized  C++ Style Reuse:  Inheritance  Composition Jan 2013 OOP in C++ 70 .

Basics of C++ Inheritance  If a class A is derived from another class B then A is called the derived/sub class and B is called the base/super class. the derived class gets the behavior of the base class  The derived class may extend the state and behavior of the base class by adding more attributes and methods. Jan 2013 OOP in C++ 71 .  All (?) data members and methods of the base class are immediately available to the derived class.  Thus.

private members of the base class are not directly accessible to the members in the derived class. private members of the base class become private members of the derived class and public members of the base class become public members of the derived class  However.Accessibility of Base Class Members  What happens to the access specifier of the members of the base class when they are derived?  Depends on the mode of derivation.  In public inheritance. Jan 2013 OOP in C++ 72 .

. }.Object Layout in Inheritance Assume the following class hierarchy class C: public B { . class A { . Jan 2013 Layout for an object of type C A-Part Data Member B-Part Data Member C-Part Data Member OOP in C++ 73 . }... }. class B: public A { .

 However. Jan 2013 OOP in C++ 74 . it is important for the derived class to have more accessibility to the members of the base class than other classes or functions.  If a member is protected then it is directly accessible to the methods of the derived class.protected Members  private data members of the base class cannot be directly accessed by the methods of the derived class.

int numberOfPeopleManaged. class Manager : public Employee { protected: Employee *supervised[10]. n). long id. public: Manager(Id. }. float getSalary(). void printSupervisedEmployeeId().Syntax of Inheritance  An example class Employee { protected: float basic. public: Employee(long id). } Jan 2013 OOP in C++ 75 . float getSalary().

Order of Constructor Calls  The constructor of the derived class is responsible for initializing the state of the derived object.  The derived object contains attributes which are inherited by the derived class. the constructor of the base class is executed first and then the constructor of the derived class is executed.  The constructor of the derived class calls an appropriate constructor of the base class  Therefore. Jan 2013 OOP in C++ 76 .

} Jan 2013 OOP in C++ 77 . int n) : Employee(id) { numberOfPeopleManaged = n. } Manager::Manager(long id.Example of Derived Class Constructor Employee::Employee(long id) { this->id = id.

Jan 2013 OOP in C++ 78 .  The derived object contains attributes which are inherited by the derived class.  The destructor of the derived class calls the destructor of the base class  Therefore.Order of Destructor Calls  The destructor of the derived class is responsible for cleaning up the state of the derived object. the destructor of the base class is executed first and then the destructor of the derived class is executed.

e-> printSupervisedEmployeeId().  Only base class part of the derived object can be seen through the base pointer. Employee *e = &m. // Employee *e = (Employee *)(&m). //error Jan 2013 OOP in C++ 79 .Casting  Derived class pointer can be implicitly cast to a base class pointer Manager m.

Casting  A Base class pointer cannot be implicitly cast to a derived class pointer Manager *pM. pM = e. //ok Down casting may be dangerous Jan 2013 OOP in C++ 80 . //error pM = (Manager *)e.

//Which getSalary? Employee or Manager?  “e” is declared as a pointer to Employee Jan 2013 OOP in C++ 81 . Employee *e = &m.  Consider the following example: Manager m. e->getSalary(). Dynamic Binding  Binding refers to associate a type to a name.Static vs.

it makes more sense to mean “getSalary” of the Manager class. //Which getSalary? Employee or Manager?  In the example however. e->getSalary().Static vs. Dynamic Binding  Continue on the example: Manager m.  We need a dynamic binding of “e” so that the type of “e” may be set at run time by pointer to the type of the actual object  This is also called late binding Jan 2013 OOP in C++ 82 . Employee *e = &m.

 If a method is not virtual and it is redefined in the derived class then the latter definition hides the former one.  If a method is declared as virtual. it can be overridden in the derived class. Jan 2013 OOP in C++ 83 . dynamic binding is made possible only for pointer & reference data types and for methods that are declared as virtual in the base class.Virtual Functions  In C++.

} virtual int g(){ return 3. j. i = b->f(). k. k = b->g(). Output will be 2 4 6 6 printf(“%d %d %d %d\n”. m).} }. main() { Y a. m = a. public: int f(){ return 4. i. k. j = a. m. int i. } Jan 2013 OOP in C++ 84 . X *b = &a.Virtual Function: Example class X{ class Y: public X{ public: int f(){ return 2. j .g().} int g(){ return 6.} }.f().

. int main() { Y y1. pX->f(). // f as defined in Y will be called } Jan 2013 OOP in C++ 85 class Y : public X { protected: void f(). }. // f as defined in X will be called pY = &y1. Y *pY. pX = &y1. }. class X() { protected: void f(). X *pX.Redefining a Non-Virtual Function  Simply do not do that. pY->f().

 Y is derived from X.  During object creation. X-part-data X-part-virtual-function-ptr Y-part-data Actual definition of the virtual function Jan 2013 OOP in C++ 86 . the actual address of the function is assigned to the function pointer.Virtual Function Table  If a class has a virtual function. then each instance of that class contains a space to store a pointer to the actual definition of that function. which has a virtual function.

 A class with one or more pure virtual function is called an abstract class.Abstract Class  Pure Virtual Function  A virtual function may be assigned to NULL meaning that this function is declared but not defined in a class.  Abstract class define a contract or interface to be used by the user of the class library and to be implemented by the developer of the class library.  Definition of such a class is incomplete. Jan 2013 OOP in C++ 87 .  Abstract class cannot be instantiated.

Virtual Destructor  Constructors cannot be virtual  For a base class which has been derived from.  Occasionally we create a derived object and store it using a pointer to Base class such as  Base *pBase = new Derived(/*arguments*/).  If the destructor in the Base class is not declared virtual then the destructor of the Derived class will not be automatically called in this example. Jan 2013 OOP in C++ 88 .  If we destroy this object using “delete pBase” then two destructors need to be called. the destructor must be declared virtual.

 Suppose three classes Triangle.  Consider a main function that creates different Shape objects and store them in an array.Inheritance Example: Polymorphic Array  Consider an abstract base class Shape which contains a pure virtual function “CalculateArea”.  If in a for loop the function calculateArea is called on all objects in the array. Jan 2013 OOP in C++ 89 . Rectangle and Circle derived from Shape. we see dynamic binding in use.

}. double x_b. double r). double y_b. double radius. b. Triangle(double x_a.. public: double calculateArea(). double x_c. double y_c). c. double y_centre.Polymorphic Array: Class Definitions class Shape { class Circle : public Shape() { public: 0. double y_a. }. class triangle : public Shape() { virtual double calculateArea() = private: Point centre. private: Point a. Circle(double x_centre. public: double calculateArea(). }. Jan 2013 OOP in C++ 90 .

Polymorphic Array: main function int main() { Shape *pArr = NULL. x_b. double x_a. &x_c. 3 for circle and 0 to quit\n”).. y_a. int n = getInput(pArr). while (1) { int j = 0. 2 for rectangle. scanf(“%d”. x_c. &y_b. &i). &x_c. &x_a. for (int i = 0. &x_b. i. case 1: scanf(“%f%f%f%f%f%f”. pArr[j++] = new Triangle(&x_a. i++) { double area = Shape[i]->calculateArea(). &y_c). y_b. . area). } } int getInput(Shape *pArr) { printf(“Which Shape do you want to create?\n”). printf (“%d %lf \n”. break. y_c. i < n. &x_b. &y_b. int i. switch (i) { case 0: break. &y_c). &y_a. &y_a. ……. } } } Jan 2013 OOP in C++ 91 printf(“Write 1 for triangle.

Inheritance: Benefits      Code Sharing/Reuse Consistency of Interface Construction of Software Components Rapid Prototyping Information Hiding Jan 2013 OOP in C++ 92 .

Inheritance: Cost     Execution Speed Program Size Message Passing Overhead Program Complexity Jan 2013 OOP in C++ 93 .

Inheritance: Limitations  operator= cannot be inherited  Can be used to assign objects of the same type only  Copy Constructor cannot be inherited  Static members are inherited in a derived class  Static members cannot be “virtual”  If you redefine a static member function. all other overloaded functions in the base class are hidden Jan 2013 OOP in C++ 94 .

} } int main() { Derived d[10]. Tell why.f(). Jan 2013 OOP in C++ 95 .  Class Base has a virtual function “f” which is redefined in Derived.  The following code is buggy.f(). b[1]. void f(Base *b) { b[0].  Derived is publicly derived from Base.Inheritance Notes  Constructors cannot be virtual  Calling a virtual function from within a constructor does not have the desired effect. f(d).

pX->f(). X *pX.Default Parameter & Virtual Function  Do not change the default parameter in a redefined virtual function class X() { protected: virtual void f(int i = 10). // f with value of i as 20 will be called } Jan 2013 OOP in C++ 96 class Y : public X { protected: virtual void f(int i =20). Y *pY. }. pX = &y1. . pY->f(). // f with value of i as 10 will be called pY = &y1. }. int main() { Y y1.

Is an Ostrich a Bird  Suppose there is a base class Bird  a virtual method fly returns altitude > 0.  A class Ostrich is derived from Bird.  Can an overridden method be empty?  Can an overridden method throw exceptions? Jan 2013 OOP in C++ 97 .  Leads to a logical dilemma.  fly method has to be redefined as an empty function.

strange things happen!  Subset is not substitutable!! Jan 2013 OOP in C++ 98 .  Suppose that Ellipse has a method setSize(x. ……. }  If sample is called on a circle. sample (Ellipse &e) { e.  Let Circle be derived from Ellipse.Is a Circle an Ellipse?  Circle is a special type of ellipse. setSize(10.y).  Also suppose that there is a function sample as defined below.20).

Should a Stack inherit from a List?  Probably Not!  If List is the base class of Stack  Methods such as push.  A Stack has a List. Jan 2013 OOP in C++ 99 . are to be defined (at least as pure virtual) in the List class.  All members of List must have (even a trivial) implementation in Stack. pop etc.

otherwise. in A is virtual. Jan 2013 OOP in C++ 100 .Multi-level Inheritance  Suppose that C is derived from B and B is derived from A.  If f is redefined in B then f is virtual even if the keyword “virtual” does not precede the declaration/definition in the derived class. an implementer of C may think that f is not a virtual method. f.  It is advisable to explicitly write “virtual” in front of the definition of f in B as.  Suppose that a method.

 Both C and B contain a function f . therefore.  A new class D is required to be derived from A later. Jan 2013 OOP in C++ 101 .Inheritance & Code Reuse  Suppose that C and B and are derived from A. f is made a virtual (not pure) function in A.  Interfaces should not have implementation.  f in D is different than A.  This is bad.

private Inheritance
 If B is privately derived from A then private, protected and public members of A become private members of B. However, private members of A are not directly accessible to B.  Thus, even if C is publicly derived from B then no member of A is accessible to C.  Functions which may access members of A in B are
 Methods of class B  Friend functions of class B.

Jan 2013

OOP in C++


protected Inheritance
 If B is protectedly derived from A then, protected and public members of A become protected members of B. However, private members of A remain private in B and are not directly accessible to B.  Functions which may access members of A in B are
 Methods of class B  Friend functions of class B.

 Methods in classes publicly derived from B
 Friend functions of classes publicly derived from B
Jan 2013 OOP in C++ 103

Private Inheritance: Implications
 public Inheritance models “is a”  private inheritance models “is implemented in terms of ”
 Assume two classes, Set and List.

 Set contains unique elements while List may contain duplicate elements.
 Thus Set is not a List  But a Set can use the code of the List class as a Set can be implemented in terms of a list.  Users of the class Set should not have an access to the List behavior even to create further derived classes
Jan 2013 OOP in C++ 104

Object-Oriented Programming in C++ TYPE CASTING Jan 2013 OOP in C++ 105 .

 The standard C++ conversions and user-defined conversions  Explicit conversions.  type is needed for an expression that cannot be obtained through an implicit conversion  more than one standard conversion creates an ambiguous situation Jan 2013 OOP in C++ 106 . expression. function argument.Type Casting  Why casting?  Casts are used to convert the type of an object.  (Silent) Implicit conversions. or return value to that of another type.

Type Casting To perform a type cast. the compiler  allocates temporary storage  Initializes temporary with value being cast float f (int i. temp_j = j. int j) { float temp_I = i.int j) { return (float ) i / j. } Jan 2013 OOP in C++ 107 . } // compiler generates: float f (int i. return temp_i / temp_j.

s3.  Automatic conversions (either conversion operators or single argument non-explicit constructors) are unsafe as well.  can silently let wrong code compile cleanly. String s1.  can interfere with overload resolutions. s3 = s2 – s1.Automatic (Implicit) Conversion  Automatic conversions from one type to other may be extremely convenient. s2. // Though “-” is not overloaded in String Jan 2013 OOP in C++ 108 .

s1 = “example”.Casting to User Defined Type  Constructors help  The following statement is not an error even when an appropriate assignment operator is not defined but an appropriate constructor is defined (which constructor?)  String s1. Jan 2013 OOP in C++ 109 .

Casting to User Defined Type  The assignment statement is converted to the following  s1 = String(“example”).  Lots of temporary objects are created.  Even the following statement is correct:  s1 = s2 + “abc” + “def”. Jan 2013 OOP in C++ 110 .

Ambiguities: Example
 Overuse of such casting may lead to ambiguities as illustrated in the following example
/* ambig.cpp */ #include “string.h” class example { public: example(const char *) { } ; }; void f1 (const String & ) { } void f1 (const example & ) { } int main ( ) { // f1 (“hello, world”) ; is ambiguous f1 ((String) “hello world” ); f1 ((example) “hello world” ); // or provide void f1 (const char *) return 0; }

Jan 2013

OOP in C++


Ambiguity: Example
class B; class A { public: A (const B &); ... }; class B { public: operator A () const; }; void f(const A &); B b; f(b); //Error - Ambiguous

 Which one to use for casting?
 Constructor in A OR  Cast Operator in B

Jan 2013

OOP in C++


Casting from Class Types
 To cast a user defined type to some other type, type casting operator is to be defined explicitly.  To convert to a type, say <type>, the following function operator <type> is to be defined.  Such functions do not have an explicit return type and do not take any argument (NATURALLY!).  The following example illustrates how a string object can be cast to a char * by defining a function “operator char *()” .

Jan 2013

OOP in C++


Example of user defined cast const int max_string_length = 128. String name = “Zaphod Beeblebrox”. // not legal. private: char text [max_string_length+1] }. String (const char *). const String &). return 0 . int main ( ) { int fd. operator const char * ( ) const . class String { public: String ( ) : String (const String & ) . void print ( ) const . String filename = “tmp/test”. O_WRONLY | O_CREAT. . String & operator = (const String & ) . name – “Beeblebrox”. close (fd). 4). write (fd. “zbc”). since we can cast only to const char * // strcpy (filename. “test”. . // cast filename to type const char * fd = open (filename. ~String ( ) . // is now ambiguous. int length ( ) const . int read ( ) . Jan 2013 void operator-(const String &. 0666). } 114 OOP in C++ .

close (fd). // is no longer ambiguous return 0.as_char_pointer ( ). const String &). String name = “Zaphod Beeblebrox”. int length ( ) const. “test”. “zbc”). . String filename = “/tmp/test”.Avoiding Ambiguities const int max_string_length = 128.. String (const String & ) . void print ( ) const.. const char *as_char_pointer ( ) const. int main ( ) { int fd. // not legal // strcpy (filename. String (const char *). name – “Beeblebrox”. ~ String ( ) . O_WRONLY | O_CREAT.as_char_pointer ( ). String & operator = (const String & ). 4). class String { public: String ( ) . void operator-(const String &. write (fd. private: char text [max_string_length+1]. // convert filename to type char * fd = open (filename. 0666). }. int read ( ). } 115 Jan 2013 OOP in C++ .

 Re-interprets representation of object  Violates data encapsulation Jan 2013 OOP in C++ 116 .Casting Pointers & References  Casting a value:  float f_var = 3.  cout << (int) f_var.14.  cout << (int &) f_var.  creates a temporary object  does not violate data encapsulation  Casting a pointer or reference  cout << *(( int *) &f_var).

C++ casts  There are four cast operators in C++     const_cast static_cast reinterpret_cast dynamic_cast  Only dynamic_cast is not equivalent to a C-style cast Jan 2013 OOP in C++ 117 .

 More narrowly specified purpose for each specified cast. Jan 2013 OOP in C++ 118 .Prefer C++ casts to C-style casts  Type conversions of any kind (either explicit via casts or implicit by compilers) often lead to code that is executed at runtime.  Easier to identify (can “grep”)  C-style casts do not have a usage semantics that compilers may use.  Some casts are performed safely at run-time. compilers can diagnose user errors.

volatile attribute(s) from a class.  A pointer to any object type can be explicitly converted to a type that is identical except for the const. the result will refer to the original object.const_cast operator  Syntax:  const_cast < type-id > ( expression )  The const_cast operator can be used to remove the const. Jan 2013 OOP in C++ 119 .  The const_cast operator cannot be used to directly override a constant variable's constant status. volatile qualifiers. Applying on pointers and references.

} Jan 2013 int main() { CCTest X. } void CCTest::printNumber() const { cout << "\nBefore: " << number.setNumber( 8 ). }  On the line containing the const_cast. void printNumber() const. The cast lasts only for the remainder of the line on which it appears. the data type of the this pointer is const CCTest *. void CCTest::setNumber( int num ) { number = num. 120 OOP in C++ . cout << "\nAfter: " << number. X. The const_cast operator changes the data type of the this pointer to CCTest *. allowing the member “number” to be modified. }. private: int number.printNumber(). const_cast< CCTest * >( this )>number--.const_cast operator: Example Example #include <iostream> class CCTest { public: void setNumber( int ). X.

 When one has a const object and has to pass it to some function that takes a non-const parameter and it is known that the function does not modify that parameter then casting away const-ness is both useful and safe. Jan 2013 OOP in C++ 121 .Usage of “const”  The example of the previous slide is not the best usage of const.  The member “number” should be “mutable” instead.

 Do not return handles to internal data from a const member function. This is not useful and misleading at best. use it as much as possible but no more.  Do not use const pass-by-value parameters in function declarations. Jan 2013 OOP in C++ 122 .  When returning a user defined type. prefer returning a const value.Guidelines for const  const is a powerful tool for writing safer code.

meaning and restrictions as C-style cast. Jan 2013 OOP in C++ 123 . It cannot be used to convert a struct into an int or a double into a pointer.static_cast operator  Syntax:  static_cast < type-id > ( expression )  The static_cast operator converts expression to the type of type-id based solely on the types present in the expression.  static_cast has basically same power.

 may also use static_cast to convert any expression to a void. in which case the value of the expression is discarded.static_cast operator  In general. Jan 2013 OOP in C++ 124 . a complete type can be converted to another type so long as some conversion sequence is provided by the language.  It cannot change the const-ness of an expression.

static_cast: Example
Example: class B { ... }; class D:public B { ... }; void f(B* pb, D* pd){ D* pd2 = static_cast<D*>(pb); // not safe, pb may point to just B B* pb2 = static_cast<B*>(pd); // safe conversion ... }.

 The static_cast operator can be used for operations such as converting a base class pointer to a derived class pointer . Such conversions are not always safe since no runtime type check is made to ensure the safety of the conversion.For such conversions dynamic_cast should be used.

Jan 2013

OOP in C++


C-style casts VS static-cast
class Base { public: Base() : _data(999) {} int Data() const { return _data; } private: int _data; }; class Derived : private Base { public: Derived () : Base() {} }; Derived *d1 = new Derived;

 The following C-style code works even if .
int i = d1->Data(); //Error! Base* b1 = (Base*) d1; int i = b1->Data(); // works! Base *b2 = static_cast<Base *>(d1); //Error!

 The old C-style casts let us cast from one incomplete type to another! static_cast does not let you do that.

Jan 2013

OOP in C++


reinterpret_cast operator
 Syntax:
 reinterpret_cast < type-id > ( expression )

 The reinterpret_cast operator allows any pointer to be converted into any other pointer type. It also allows any integral type to be converted into any pointer type and vice versa.  The reinterpret_cast operator can be used for conversions such as char* to int*, or One_class* to Unrelated_class*, which are inherently unsafe.
Jan 2013 OOP in C++ 127

 The reinterpret_cast operator cannot cast away the const. non-portable.reinterpret_cast operator  The result of a reinterpret_cast cannot safely be used for anything other than being cast back to its original type. Other uses are. at best. volatile attributes.  One practical use of reinterpret_cast is in a hash function.  Reinterpret_cast should rarely be used in a C++ program Jan 2013 OOP in C++ 128 . which maps a value to an index in such a way that two distinct values rarely end up with the same index.

for ( int i = 0. }  The reinterpret_cast allows the pointer to be treated as an integral type. i++ ) cout << Hash( a + i ) << endl. The index is then truncated by a standard C-style cast to the return type of the function. } int main(){ int a[20]. The result is then bit-shifted and XORed with itself to produce a unique index (unique to a high degree of probability). Jan 2013 OOP in C++ 129 . return ( unsigned short )( val ^ (val >> 16)). i < 20.reinterpret_cast: Example Example #include <iostream> unsigned short Hash( void *p ){ // Returns a hash code based on an address unsigned int val = reinterpret_cast<unsigned int>( p ).

Dd1. B b1. class B : private virtual A { …}. const A a2. class D : public B. A a1. const A& ra2 = a2. public C { …}. Jan 2013 OOP in C++ 130 .  Use static_cast instead.  Use reinterpret_cast  A *pa = (A*)&a2.  A *pa = (A *)&ra1.  B *pb = (B*)(pv).  Use const_cast  B * pb = (B*)&c1.  void *pv = &b1. C c1. class C : public A { … }. const A& ra1 = a1.Usage of casts class A { public: virtual ~A().  Cannot be expressed in a new-style cast. …}. char c.

Jan 2013 OOP in C++ 131 ... // then call its onResize.. // do SpecialWindow} // specific stuff . static_cast<Window>(*this).Avoid Unnecessary Cast  Look at the cast and comment class SpecialWindow: public Window { // derived class public: virtual void onResize() { // derived onResize impl.onResize(). }. // cast *this to Window. // this doesn’t work! ..

respectively.type_info class  The type_info class describes type information generated within the program by the compiler.  The operators “==“ and “!=“ are overloaded and can be used to compare for equality and inequality with other type_info objects. The entire definition of this class is implementation dependent but the following features of this class is standardized. Jan 2013 OOP in C++ 132 . The type_info class also stores an encoded value suitable for comparing two types for equality or collating order.  Objects of this class effectively store a pointer to a name for the type.

Jan 2013 OOP in C++ 133 .  Type information is generated for polymorphic classes only if the /GR (Enable Run-Time Type Information) compiler option is specified. The memory pointed to is cached and should never be directly deallocated.type_info class  Features of type_info class (contd):  The “name” member function returns a const char* to a null-terminated string representing the humanreadable name of the type.

where the true type of the object cannot be determined by the static information provided. Such cases are: a reference/ Pointer Jan 2013 OOP in C++ 134 .  The result of typeid is a const type_info&.typeid operator  Syntax: typeid( type-id ) OR typeid(expression)  The typeid operator allows the type of an object to be determined at run time.  The typeid operator does a run-time check when applied to an l-value of a polymorphic class type.

Jan 2013 OOP in C++ 135 .  type-id may be used with operands of built-in types. the result is the type of the operand not the type of the underlying object.typeid operator  When the operand of typeid is of a nonpolymorphic class type.

//prints "class Derived" delete pd. the result will be the type_info for the pointer. Without de-referencing the pointer.  The pointer must be dereferenced so that the object it points to is used.h> class Base { public: virtual void vvfunc() {} } class Derived : public Base {}. //prints "class Base *” cout << typeid( *pb ).typeid:Example The expression usually points to a polymorphic type (a class with virtual functions).name() << endl. //prints "class Derived" cout << typeid( pd ). //prints "class Derived *" cout << typeid( *pd ). cout << typeid( pb ). Base* pb = pd. not pointee Example  #include <iostream> #include <typeinfo.name() << endl. } . Jan 2013 OOP in C++ 136 int main(){ Derived* pd = new Derived.name() << endl.name() << endl.

. pb points to B subobject of pd .. // ok: C is a direct base class..  It is used for downcasting.. }  The expression dynamic_cast<typeid>( expression) converts the operand expression to an object of type type-id.. // ok: B is an indirect base class . class C : public B { . }.. void f(D* pd){ C* pc = dynamic_cast<C*>(pd)... Jan 2013 OOP in C++ 137 . }. class D : public C { .dynamic_cast operator  Syntax:  dynamic_cast<typeid> (expression) Example class B { . }. pc points to C subobject of pd B* pb = dynamic_cast<B*>(pd).

} Jan 2013 OOP in C++ 138 .. D* pd = dynamic_cast<D*>(pb).. D* pd2 = dynamic_cast<D*>(pb2). void f(){ B* pb = new D... }.... }. // pb2 points to a B not a D the cast is bad so pd2 is NULL .dynamic_cast: Example Example: class B { . class D : public B { . // unclear but ok B* pb2 = new B. // ok: pb actually points to a D ..

or cast a base class pointer to a derived class pointer. cast a derived class pointer to another derived (sibling) class pointer. an exception is thrown. The dynamic_cast operator can be used to cast from a derived class pointer to a base class pointer. Each of these conversions may also be applied to references. the result of the dynamic_cast is null.  dynamic_cast is performed at run-time. Jan 2013 OOP in C++ 139 .dynamic_cast  If dynamic_cast to a pointer type fails.  dynamic_cast can be used only for pointer or reference types to navigate a class hierarchy. if dynamic_cast to a reference type fails.

These conversions may. However. be performed on both nonpolymorphic and polymorphic types.dynamic_cast  dynamic_cast operator cannot be used for built-in types.  dynamic_cast is strongly recommended to be applied on polymorphic types. even these results may be wrong in the presence of multiple inheritance. These conversions will produce the same result if they are converted using a static_cast.  All of the derived-to-base conversions are performed using the static (compile-time) type information. therefore. Jan 2013 OOP in C++ 140 .

 Size of the objects do not increase for RTTI operations.Cost of dynamic_cast  The pointer to the type_info object of a class is stored in the vtbl array of the class. the space cost for RTTI is an additional entry in each class vtbl plus the cost of storage for the type_info object for each class.  Cost of RTTI at run time is similar to the cost of calling a virtual function.  Thus. cost of calling a virtual function is the same as the cost of calling a function through a function pointer. Jan 2013 OOP in C++ 141 .

Object Oriented Programming in C++ EXCEPTIONS Jan 2013 OOP in C++ 142 .

Topics  Basic Concept of Exceptions  try-catch block in C++  Semantics of throw Jan 2013 OOP in C++ 143 .

Jan 2013 OOP in C++ 144 .Error Handling in C++  Error Condition Handling .C Style  via return value  return statement is dedicated for passing error conditions  by output parameter  normal and abnormal control flow tend to mix  Reusing code for error handling is difficult.

 A function catches exception objects generated from the function it calls in a distinct control flow.Error Handling in C++  Error Condition Handling .C++ Style  On error condition an exception object is created and thrown.  Similar Exception objects can enjoy benefits of inheritance. Jan 2013 OOP in C++ 145 .

}  A Calculator need to handle divide by zero  Could set value to NAN  But. program would need to check for special value (and might ignore)  Could return –1  Again program could ignore  Might be a valid return value Jan 2013 OOP in C++ 146 .C-Style Error Handling int Calculator::divide (int i) { if (i == 0) { // what do we do? } else { value /= i. } return value.

 “try” block encloses code that has usual flow of control and can potentially throw exceptions  “catch” block can occur after a “try” block or another “catch” block  catch blocks can catch and handle exceptions of different types Jan 2013 OOP in C++ 147 .“try” and “catch”  A function has its usual prototype and it may throw a number of exceptions on detecting several error condition.

a suitable Exception object is thrown. throw initiates unwinding of the call stack till the exception is handled. Jan 2013 OOP in C++ 148 .Exception Object and throw  Exception object is just another object having members (attributes and methods) suitable to model the state and behavior of an object representing an error condition.  Whenever an error condition is detected.  Creation of an object (function of new)  passing control from this function to the caller function (similar to return)  Unlike return. Semantics of throw is as follows.

divide (0). value /= i. } return 0. Calculator c. try { c. public: print() { cout << dividend << “is divided by zero” <<endl. return 1.print(). char **argv) { int i = 0. } DivideByZero(int d) { dividend = d. cout << c.getValue (). int Calculator::divide(int i) throws DivideByZero { if (i ==0) throw DivideByZero(value). } }.Example of Exception Handling in C++ class DivideByZero { private: int dividend. } Jan 2013 OOP in C++ 149 . } catch (DivideByZero& ext) { ex. return value. } int main (int argc.

 Control passes to first matching catch block  Can handle the exception and continue  Can free resources and re-throw Jan 2013 OOP in C++ 150 .Details of throw  Normal program control flow is halted  At the point where an exception is thrown  The program call stack “unwinds”  Stack frame for each function up call chain is popped  Stack variables in each popped frame are destroyed  Until an enclosing try/catch scope is reached where the type of exception thrown is caught.

 catch blocks after a try block are examined in order when an exception is thrown from a function called in the try block.More on “try” and “catch”  Whenever a function is called in a try block. the “catch” blocks to be examined after the try block are known as the extended prototype of a function includes the throw clauses.  Parentheses for each catch block has semantics of a “function argument declaration” Jan 2013 OOP in C++ 151 .

Jan 2013  Make promises to the caller  Allow stronger type checking enforced by the compiler  By default. // promises to only throw int void Calculator::divide (int i) throw (int). // promises not to throw void Calculator::add (int i) throw (). a function can throw anything it wants  A throw clause in the signature     Limits what a function can throw A promise to the calling function Promises nothing will be thrown Comma separated 152  A throw clause with no types  Can list multiple types OOP in C++ .Exception Specifications // can throw anything void Calculator::subtract (int i).

e. Contains:     The frame pointer The return address for the call (i.. where it was called from) Parameters passed to the function Automatic (stack) variables for the function 153 Jan 2013 OOP in C++ .Stack Frame automatic variables parameters previous frame pointer return address  g++ -s gives assembler output that can be used to deduce exact structure for a given platform  In general. the overall structure is common  A chunk of memory representing a function call  Pushed on program call stack at runtime.

divide (0). Calculator c. char **argv) { int i = 0. } catch (int) { return 1.Illustrating the Call Stack int main (int argc. try { c. } return 0. } Note that parameters are initialized at frame creation Variables are not necessarily initialized at frame creation  May occur later in called function i main c value_ argv 154 argc OOP in C++ Jan 2013 . cout <<  Stack frame for function main    Pushed on program call stack With stack variables i and c With parameters argc and argv   c.get_value ().

try { c.get_value ().Illustrating the Call Stack. } i main c value_ argv 155 argc OOP in C++ Jan 2013 . cout <<  Enter function main  Stack variable initialized to 0 c. Calculator c. char **argv) { int i = 0. cont.divide (0). } catch (int) { return 1. int main (int argc. } return 0.

divide (0). cont. } catch (int) { return 1. Calculator c. }  Call Default Constructor for c     Push a new stack frame No parameters or automatic variables for that specific function Params depend on function signature declaration Automatics depend on function body definition Calculator:: Calculator( ) i main this c value_ argv 156 return 0. } argc OOP in C++ Jan 2013 . char **argv) { int i = 0. try { c. cout << c. int main (int argc.get_value ().Illustrating the Call Stack.

Illustrating the Call Stack. cont. } Jan 2013 OOP in C++ Calculator:: Calculator() this i main c value_ argv 157 argc . Calculator::Calculator () : value_ (0) {} void Calculator::divide (int i) throw (int)   Enter function Calculator::Calculator ( )  Member variable value_ of stack variable c is initialized to zero There may be multiple Calculator instances Answer: implicit “this” parameter in stack frame How do we know which value_ to set?   { if (i == 0) { throw i. } else { value_ /= i. } cout << value_.

} else { value_ /= i. } Jan 2013 main i c value_ argv 158 argc OOP in C++ . return to previous Calculator::divide (int i) throw (int) { if (i == 0) { throw i. cont.Illustrating the Call Stack. } cout << value_. Calculator::Calculator () : value_ (0) { } void  Return from function Calculator::Calculator ( )  Pop the stack frame.

Illustrating the Call Stack.  Call divide method on c     Push a new stack frame Contains parameters this and i Copy address of current instance into this Copy value 0 into i this i main argc argv 159 cout << c. try { c.get_value (). cont.divide (0). char **argv) { int i = 0. } Jan 2013 void Calculator:: divide (int ) i value_ c OOP in C++ . Calculator c. } return 0. } catch (int) { return 1. int main (int argc.

} cout << value_.Illustrating the Call Stack. } else { value_ /= i. } void Calculator:: Calculator (int ) i main this c i value_ argv 160 argc Jan 2013 OOP in C++ . cont. Calculator::Calculator () : value_ (0) { }  Enter function Calculator::divide (int)   Test i equal to 0 and take the true branch Throw integer i void Calculator::divide (int i) throw (int) { if (i == 0) { throw i.

}     Thrown exception unwinds call stack Notice control skips over cout statement to end Pop the stack frame.Illustrating the Call Stack. } else { value_ /= i. cont. } cout << value_. return to previous Return from function void Calculator::divide ( ) i main c value_ argv 161 argc OOP in C++ Jan 2013 . Calculator::Calculator () : value_ (0) { } void Calculator::divide (int i) throw (int) { if (i == 0) { throw i.

} catch (int) { return 1. Calculator c. } We‟ve reached an enclosing try/catch scope  So stack unwinding stops Control jumps to first matching catch block  Again. } return 0. try  { c.divide (0). char **argv)  { int i = 0.get_value (). skips over intervening cout statement i main c value_ argv 162 argc Jan 2013 OOP in C++ . int main (int argc. cout << c. cont.Illustrating the Call Stack.

. } catch (.) // catch all.More on catch try { // can throw an exception } catch (Derived &d) { // ... }  Control jumps to first matching catch block    Order matters with multiple possible matches Especially with inheritance-related exception classes Hint: put catch blocks for derived exception classes before catch blocks for their respective base classes More specific catch before more general catch catch (…) catches any type 163 catch (Base &b) { // . }   OOP in C++ Jan 2013 ... { // ......

{ // ... } catch (....) // catch all. }  Notice catch-by-reference for user defined types   More efficient      Only a reference propagates Rather than entire object Avoids class-slicing problem if catch as base type.. // rethrows e } catch (int) { // . throw.. rethrow Preserves polymorphism More on this in later lectures More correct  Can leave off variable name  Unless catch block needs to do something with the instance that was caught 164 Jan 2013 OOP in C++ ...A Few More on catch try { // can throw an exception } catch (MyClass &e) { // ..

Object-Oriented Programming in C++ TEMPLATES Jan 2013 OOP in C++ 165 .

 We need to define different classes.  Classes list.What is a Template?  Templates are specifications of a collection of functions or classes which are parameterized by types. list of objects.  Examples:  Function search. Jan 2013 OOP in C++ 166 ..  But. min etc.  The data members and the methods are almost the same for list of numbers. however. we need to write different versions of these functions for strong type checking in C++.  The basic algorithms in these functions are the same independent of types. queue etc.

X &other) { { int temp. i = j. j = temp. Type parameter one = other. temp = one. } } void swap(String &i. int &j) template<class X> void swap (X &one. String s1(“abc”). s2(“def”). } } Template instantiation Jan 2013 OOP in C++ 167 . Type parameter list other = temp. temp = i. swap(I. j = temp. j=20. X temp. s2). j). temp = i. i = j. int I=10.Function Template: An Example void swap(int &i. swap(s1. String &j) { Main() { String temp.

parameters 168 OOP in C++ . (i.Parameterized Functions  A function template  describes how a function should be built  supplies the definition of the function using some arbitrary types.  a parameterized definition  can be considered the definition for a set of overloaded versions of a function  is identified by the keyword template  followed by parameter identifiers  enclosed between < and > delimiters  noting they are Jan 2013 class. (as place holders). type).e.

size is replaced with a constant value known at compile time  The actual value for a non-type parameter must be a constant expression.Template Non-type Parameter  It is an ordinary parameter  template <class T. Jan 2013 OOP in C++ 169 . int size> T min (T (&x[size])).  When min is called.

typename  The key words class and typename have almost the same meaning in a template parameter  typename is also used to tell the compiler that an expression is a type expression template <class T> f (T x) { T::name * p. // Is this a pointer declaration or multiplication? } template <class T> f (T x) { typename T::name * p. // Is this a pointer declaration or multiplication? } Jan 2013 OOP in C++ 170 .

Template Argument Deduction  Each item in the template parameter list is a template argument  When a template function is invoked. int pval[9]. //Error!! Jan 2013 OOP in C++ 171 . int size> Type min( T(&x[size])). min(pval). the values of the template arguments are determined by seeing the types of the function arguments template <class T.

Array-to-pointer conversion)  Qualification conversion  Conversion to a base class instantiation from a class template  If the same template parameter are found for more than one function argument. template argument deduction from each function argument must be the same Jan 2013 OOP in C++ 172 .  L-value transformation (e.Template Argument Deduction  Three kinds of conversions are allowed.g..

1024). min (ui.  sum(ch. „a‟). U y)  min<int>(i. // OK  Specifying return type generically is often a problem.  unsigned int ui. class U> R sum(T x. T y). U y). ch) returns T  template < class R. Jan 2013 OOP in C++ 173 . class U> ??? sum(T x. sum (ui.  template <class T. ui) returns U.Explicit Template Arguments  It is possible to override template argument deduction mechanism and explicitly specify the template arguments to be used.  template <class T> T min(T x. 1024). class T. //Error!!  min<unsigned int>(ui.

 The following template is not good for char * template <class T> T min(T x.Template Explicit Specialization  Some times. } Jan 2013 OOP in C++ 174 . a template may not be suitable for all types. }  Define the function explicitly for char * template<> char * min <chr *>(char *x. char *y) { return ((strcmp(x. T y) { return (x < y) ? x : y). y) < 0) ? x : y).

int how_many. how_many++. int put (const T &val). T *get (). if (end_ptr) end_ptr->next_item = tmp_ptr. int unget (const T &val). else beg_ptr = tmp_ptr. *end_ptr. private: struct Node { Node *next_item. return 1. template<class T> int List<T>:: put (const T &val) { Node *tmp_ptr = new Node. end_ptr = tmp_ptr. virtual ~List (). T *unput (). } *beg_ptr. int length (). } else return 0.A List Template Class template<class T> class List { public : List (). } Jan 2013 OOP in C++ 175 . }. T *find(const T &val). T *list_item. if (tmp_ptr && (tmp_ptr->list_item = new T (val) ) ) { tmp_ptr->next_item = 0.

List<String> is.Using a Template Class int main () { register int i. cout << ii. List<int> ii. “seven”. “two”.length () << “ items\n” . i++) { ii. “nine”. “ten”}. “five”. String *sptr. } cout << “The List<int> contains “ . char *somedata [] = {“one”. *iptr. return 0. for (i = 1.put(i). “six”. “three”. “four”. “eight”. i <=10. } Jan 2013 OOP in C++ 176 .

(as a place holder).  is a parameterized type with parameterized member functions Jan 2013 OOP in C++ 177 .Parameterized Class  A class template  describes how a class should be built  Supplies the class description and the definition of the member functions using some arbitrary type name.

parameters  is often used for “container” classes Jan 2013 OOP in C++ 178 .Parameterized Class  can be considered the definition for an unbounded set of class types  is identified by the keyword template  followed by parameter identifiers  enclosed between < and > delimiters  noting they are class.e. type). (i.

templates)  MUST support the methods used by the template functions:  what are the required constructors ?  the required operator functions ?  What are the necessary defining operations ? OOP in C++ 179 Jan 2013 .Parameter Requirements Parameter Types  may be of any type. (i. (including user defined types)  may be parameterized types.e.

a method is invoked)  A template definition can refer to a class template or its instances but a n non-template can only refer to template instances. Jan 2013 OOP in C++ 180 .Class Template Instantiation  Class Template is instantiated only when it is required. //OK  Class template is instantiated before  An object is defined with class template instantiation  If a pointer or a reference is de-referenced (e.     Matrix is a class template Matrix m. // OK void inverse (Matrix & m).g.. //error Matrix *pm.

Friend & Static Declaration  There are 3 kinds of friend declarations  Non-template friend. Jan 2013 OOP in C++ 181 .  A bound friend class template.   Operators can be overloaded for a class template  A static data member in a class template is itself a template.  Each static data member instantiation corresponds to a class template instantiation.  One-to-one mapping between the instance of a class template and its friend One-to-many mapping between the instance of a class template and its friend  An unbound friend class template.

Source code organization  Inclusion Model  Make the template definition visible to compiler at the point of instantiation  Include source files as well.  Separation Model  Use keyword „export‟ in front of definition.  Increase in build and link time  Instantiate the types you need explicitly in a separate compile unit.  Jan 2013 Not many compiler supports the feature. OOP in C++ 182 .  Cannot use benefits of lazy instantiation.

. Jan 2013 OOP in C++ 183 . must define ALL members equating them to specialization  Class templates can be partially specialized too.Template specialization  Allows to make specific implementation when pattern is of determined type.  The syntax is template<> class XXX<Type> {.  A totally disjoint template that the compiler gives a priority while instantiation. So.}  No member is „inherited‟ from the generic template to specialized one.

 specialContainer<Node. A.Templates & Derivation  A template expresses a commonality across types  Two types generated from a common template are different. Shared> s1.  Example  template <class T. OOP in C++ 184 .  specialContainer<ProcessDescriptor.  specialContainer<Node. Fast_Allocator> Jan 2013 p.  A Base class expresses commonality of representation and calling interface. Fast_Allocator> s. class A> class specalContainer : public Container<T>.

} template<class T> int Set<T> : : length ( ) { return items. } template<class T> int Set<T> ::find (const T &val) { return (int) items. } Jan 2013 OOP in C++ 185 . items. virtual void add (const T &val).find(val). int find (const T &val). }. private: List<T> items. template<class T> void Set<T> : : add (const T &val) { if (items.length ( ) .Template Inheritance: A Base Template template<class T> class set { public : Set ( ) { } .put (val) .find (val) ) return. int length ( ) .

}. max (upper) { } template<class T> void BoundSet<T> : :add(const T &val) { if (find (val) ) return.h” template<class T> class BoundSet : public Set<T> public: BoundSet (const T &lower. } 186 Jan 2013 OOP in C++ . T max.h */ #include “set. void add(const T &val). private: T min. if ( (val <= max) && (val >= min) ) Set<T>: : add (val) . const T &upper) : min (lower). const T &upper).Template Inheritance: A Derived Template /* boundset. template<class T> BoundSet<T>:: BoundSet (const T &lower.

} Jan 2013 OOP in C++ 187 . 21).find(25 ) ) { cout << “We found an Unexpected value\n”.find (0) || bsi.Using a Derived Template Class int main ( ) { register int i . if (bsi. return 23. BoundSet<int> bsi (3. i++) setptr->add( i ) . } else cout << “We found NO unexpected value\n”. Set<int> *Setptr = &bsi.find (4) cout << “We found an expected value\n”. for (i = 0. return 0. if (bsi. i < 25.

 Template class knows the type of the class at compile-time instead of having to determine it at run-time (as in case of virtual function usage) Jan 2013 OOP in C++ 188 .  Compiler view  Constructor of objects containing virtual functions must initialize the vptr table.Inheritance vs Templates  Inheritance : helps in reusing object code  Templates : helps in reusing source-code  object code size of template code is therefore much less.

rdbuf(). ios::in) : cin) . out.is_open() ? out : cout).is_open() ? in : cin. # ECHO infile outfile main() { (argc > 2 ? ofstream (argv[2] . } main() { fstream in.Inheritance vs Templates: Example Implement the following command. ios::out).ios::out) : cout) << (argc > 1 ? ifstream (argv[1]. if (argc > 2) out. ios::in).open(argv[2].open(argv[1]. out. Process(in. if (argc > 1) in. }  How to implement ‘Process’ ?  Two ways to get the polymorphic behavior  virtual function and templates Jan 2013 OOP in C++ 189 .

rdbuf(). } void Process (basic_istream& in. ) Jan 2013   Both Methods solve the current problem.rdbuf().Inheritance vs Templates: Solution template<typename In. typename out> void process(In& in. Out& out) { // out << in. Other streams cannot be guaranteed to be derived from the same base class 190 OOP in C++ . }  Requirement:   cin and ifstream both derived from basic_istream The common base class „basic_istream has suitable interface „rdbuf‟.   Other streams can be provided with rdbuf() interface. But templates provide extensibility.  Merely requires that the passed objects to have suitable interface (such as member function named rdbuf(). basic_ostream& out) { // out << in.

Has features : move.  If „type‟ does not affect the behavior.  Analyze if the „type‟ being manipulated has any affect on the behavior of class . Each provide different level of comfort. use virtual functions (inheritance) Jan 2013 OOP in C++ 191 . For airplane.     Has operations: push. use templates  If „type‟ affects the behavior.Another Example  A collection of classes is required for  Stack: for ints . pop.  transportationMode . comfort etc each move in diff ways. car. boat etc. length of stack. strings. floats etc.

Thank You .

Sign up to vote on this title
UsefulNot useful

Master Your Semester with Scribd & The New York Times

Special offer: Get 4 months of Scribd and The New York Times for just $1.87 per week!

Master Your Semester with a Special Offer from Scribd & The New York Times