KEMBAR78
OOP in C++ | PPT
Object-Oriented
Programming in C++
Jan-Feb 2014
Lecture 02-
PROGRAMMING IN C++
Object-Oriented Modeling & Programming
OOP in C++ 2Jan 2014
Topics
 Procedural Enhancements in C++ over C
 Classes
 Overloading
 Inheritance
 Type Casting
 Exceptions
 Templates
3OOP in C++Jan 2014
PROCEDURAL
ENHANCEMENTS IN C++
Object Oriented Programming in C++
Jan 2014 4OOP in C++
TOPICS
 Const-ness
 Reference Data Type
 Inline Functions
 Default Function Parameters
 Function Overloading & Resolution
 Dynamic Memory Allocation
5OOP in C++Jan 2014
const Quantifier
 const qualifier transforms an object into a
constant.
 Example: const int capacity = 512;
 Any attempt to write a const object is an error
 Const object must be initialized.
 Pointer to a non-constant object can not point to
a const object;
const double d = 5.6;
double *p = &d; //error
 Pointer to a constant object vs. constant pointer
to an object.
const double * pConstantObject;
double * const *pConstantPointer;
6OOP in C++Jan 2014
References
 A reference is an additional name /
alias / synonym for an existing variable
 Declaration of a Reference
<type> & <name> = <existing variable>;
 Examples of Declaration
int j = 5;
int& i = j;
7OOP in C++Jan 2014
References
 Wrong declarations
 int& i; // must be initialized
 int& j = 5; // may be declared as const reference
 int& i = j+k; // 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
8OOP in C++Jan 2014
References Do not ..
 Cannot have an array of references
 No operator other than initialization are valid on a
reference.
 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.
9OOP in C++Jan 2014
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
10OOP in C++Jan 2014
Returning a Reference
#include <iostream>
using namespace std;
int& max(int& i, int& j) {
if (i > j)
return i;
else
return j;
}
int main(int, char *[]) {
int x = 42, y = 7500, z;
z = max(x, y) ; // z is now 7500
max(x, y) = 1 ; // y is now 1
cout << "x = " << x;
cout << " y = " << y;
cout << " z = " << z << "n";
return 0;
}
11OOP in C++Jan 2014
Pointers vs. References
 Pointers can point to NULL whereas References
cannot. There is nothing defined as NULL
Reference.
 Pointers can point to different variables at
different times whereas for a reference, its
referent is fixed.
 References make code faster since, unlike
pointers, checks for NULL are not required.
 Reference “refers” to an address but does not
store that address. Pointer does.
12OOP in C++Jan 2014
Macros
 Macros are expanded at the places of their calls.
 Advantages:
 Speed-wise efficient
 Disadvantages:
 Parameter passing mechanism is not robust and
frequently leads to errors.
 Type checking during parameter passing is not done
 Code size tend to increase
 Typical Use:
 Small code re-use
13OOP in C++Jan 2014
Inline Functions
 Inline functions act like functions
 They can be class members
 Type checking is performed
 They can be overloaded
 They obey normal parameter passing rules
 But they are implemented like macros
 Code is substituted inline, not called
 Use is faster than calling a function
 Use may take more space
 They are defined in .h files, not in .c/.cxx files
14OOP in C++Jan 2014
Inline Notes
 inline specification is only a
recommendation.
 A recursive or a large function may not
be inline.
 Unlike a non-inline function, an inline
function must be defined in every text
file where it is called.
 Inline functions must not have two
different definitions.
 May cause unexpected behavior if compiler
does not chose to make the function inline.
15OOP in C++Jan 2014
Default Function Arguments
 Default arguments are appropriate argument
value of a parameter for a majority of cases.
 Default arguments can be supplied to one or
more parameters.
 Default arguments may be expressions also.
 All parameters to the right of a parameter with
default argument must have default arguments.
 Default arguments cannot be re-defined.
 Default parameters should be supplied only in a
header file and not in the definition of a function.
16OOP in C++Jan 2014
Default Arguments: Example
 Following are some examples of
functions with default arguments.
Void ff (int, float = 0.0, char *); // Error
Void ff2(int, float = 0, char *=NULL); // OK
Void ff2(int float = 1, char *= NULL); // Error – Redefinition
Assume that ff.h contains the following declaration
ff(int, float, char = ‘a’);
Wrong example:
#include “ff.h”
ff(int i, float f = 0.0, char ch = ‘a’); //Error
However, the following are correct.
#include <ff.h>
ff(int i, float f = 0.0, char ch); //OK
ff(int i = 0, float f, char ch); //OK
17OOP in C++Jan 2014
Function Overloading
 The same function name may be used in several definitions.
 Functions with the same name must have different number of
formal parameters and/or different types of formal
parameters.
 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 re-
declare”.
 Overloading allows static polymorphism
18OOP in C++Jan 2014
Overload Resolution
 Steps to resolve overloaded functions
with one parameter
 Identify the set of candidate functions and
the set of viable functions.
 Select the best viable function through
(Order is important)
 Exact Match
 Promotion
 Standard type conversion
 User defined type conversion
19OOP in C++Jan 2014
Overload Resolution
 Steps to resolve overloaded functions
with one parameter
 Example:
1. void f();
2. void f(int);
3. void f(double, double = 3.4);
4. void f(char, char *);
f(5.6)
Candidate function: 2 & 3
Best function: 3
20OOP in C++Jan 2014
Exact Match
 lvalue-to-rvalue conversion
 Most common
 Array-to-pointer conversion
Definitions: int ar[10]; void f(int *a);
Call: f(ar)
 Function-to-pointer conversion
Definitions: int (*fp) (int);
void f(int x, fp); int g(int);
Call: f(5, g)
 Qualification conversion
 Converting pointer (only) to const pointer.
21OOP in C++Jan 2014
Promotion & Conversion
 Examples of Promotion
 char to int; 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
22OOP in C++Jan 2014
Examples of Resolution
1. Promotion
enum e1 { a1, b1, c1 };
enum e2 { a2, b2, c2 = 0x80000000000 };
char *f(int); char *f(unsigned int);
int main() {
f(a1); //Which f?
f(a2); //Which f?
}
2. Standard Conversion
void print(int); void print(char *);
void set (int *);
void set (const char *);
int main() {
print (0); //Which print?
set (0); //Which set?
}
3. Conversion Sequence
int arr[3];
void putValues(const int *);
int main() {
putValues(arr);
}
23OOP in C++Jan 2014
new/delete operators
 In C++, the new and delete operators provide built-in
language support for dynamic memory allocation and de-
allocation.
int *pI = new int;
int *pI = new int(102); //new initializes!!
int *pArr = new int[4*num];
Arrays generally cannot be initialized.
const int *pI = new const int(100);
Array of constant cannot be created.
delete pI;
delete [] pArr;
 new is polymorphic
 new does more than malloc!
24OOP in C++Jan 2014
new/delete & malloc/free
 All C++ implementations also permit use of
malloc and free routines.
 Do not free the space created by new.
 Do not delete the space created by malloc
 Results of the above two operations is memory
corruption.
 Matching operators
 malloc-free
 new-delete
 new[] – delete []
 It is a good idea to use only new and delete in
a C++ program.
25OOP in C++Jan 2014
CLASS
Object Oriented Programming in C++
Jan 2014 26OOP in C++
TOPICS
 Class Members
 Constructor & Destructor
 Friends
 Static Members
 Struct & Union
27OOP in C++Jan 2014
Class
 C++ Class is an implementation of “type”
 In C++, class is the only way to implement user defined
data types.
 A C++ class contains data members/attributes to specify the
state and operations/methods to specify the behavior.
 Thus, classes in C++ are responsible to offer needed data
abstraction/encapsulation of Object Oriented Programming.
 C++ Classes also provide means (through access specifier)
to enforce data hiding that separates implementation from
interface.
28OOP in C++Jan 2014
Class
 A Class is defined by “class” keyword.
 Each member in a class has an access specifier.
 private – these members are accessible inside the definition
of the class.
 public – these members are accessible everywhere.
 Objects/instances of classes are to be created statically or
dynamically.
 Members can be accesses by “.” operator on the object.
 The implicit this pointer holds the address of any object.
 this pointer is implicitly passed to methods.
29OOP in C++Jan 2014
A Simple Class
class Employee {
public:
void setName (const char *x)
{ name = strdup(x); }
void setSalary (float y)
{ salary = y; }
char *getName ( ) { return
name; }
float getSalary ( ) { return
salary; }
private:
char *name;
float salary;
};
int main ()
{
Employee e1; Employee *e2;
e2 = new Employee;
e1.setName(“Amit”); e2->name =
strdup(“Ashis"); // Error
e2.setSalary(29100); e2-
>setSalary(29100);
}
Re-look at
void setName (const char *x) {
name = strdup(x); }
Whose name?
void setName (const char *x) {
this->name = strdup(x); }
Jan 2014 OOP in C++ 30
More on this
 Type of this
 X * const
 Necessity of this to the programmer
 Distinguishing data member from non-member
variable
 Explicit Use
class DoublyLinkedNode DoublyLinkedNode::append(DoublyLinkedNode *x)
{ {
DoublyLinkedNode *prev, *next; next = x;
int data; x->prev = this;
public: }
void append(DoublyLinkedNode *x);
}
31OOP in C++Jan 2014
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 are created in the
stack/static Store when their definition is encountered.
 Objects can be created in the Free store with a pointer storing
the address.
 allow the class to initialise the state of an object
32OOP in C++Jan 2014
Constructor Functions
 Constructor functions:
 Constructors also allocate additional memory
space from the Free store (if) required for the
object.
 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.
 If users do not define any constructor then the
compiler provides a default constructor.
33OOP in C++Jan 2014
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.
 If there is at least one definition of
constructor but no default constructor
then the following statements are
incorrect
 X a;
 X *pX = new X();
34OOP in C++Jan 2014
Destructor Functions
 Destructor function:
 is a member function named “~ <class-name>” (e.g. ~
String ( ) )
 is automatically called when an object is destroyed,
just before memory is freed
 For auto variables when the variable goes out of scope
 For objects created in the Free store, 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.
35OOP in C++Jan 2014
Copy Constructor
 Copy constructor is a special constructor
which is used to initialize an object with
another object of the same type.
 Copy constructor of class X takes an
argument of type X &.
 If the type of argument is X in stead of X&, an
infinite loop results.
36OOP in C++Jan 2014
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.
37OOP in C++Jan 2014
A Sample Class : String
class String {
public:
String();
String(const String&); // Copy Constructor
String(const char *);
~ String();
int length();
int read();
void print();
private:
char *data;
int len;
}
38OOP in C++Jan 2014
Class String::Constructor &
Destructor
String::String() {
data = NULL;
len = 0;
}
String::String(const char *s) {
data = new char[strlen(s)+1];
len = strlen(s);
strcpy(data, s);
}
void ~String() {
if (data != NULL)
delete [] data;
}
int main()
{
String s1; //default constructor
String s11(); //Error
String s1(“test”);
char str[6];
strcpy(str, “Hello”);
String s2(str);
String s3(s2); //Copy Constructor
String s4 = new String(“one”);
String s5 = new String();
delete s4;
delete s5;
}
39OOP in C++Jan 2014
Arrays
 Using Default constructor while
creating an array of objects
 String arrayOfString[100]; // 100 objects created using the default
constructor
 Using specialized constructor while
creating an array of objects.
 String arrayOfString[2] = { String(“abc”), String(“def”) };
 Using different constructor for creating
array objects dynamically.
 String *pArrayOfString[2] = { new String(“abc”), new
String(“def”) };
40OOP in C++Jan 2014
Object Layout
 Simplistically, an object
of a class must have
enough space to store all
members of that class.
 No space is required per
object for storing function
pointers for the methods
declared in the class.
 Methods on objects are
translated by the
compiler to C-like
function calls by passing
this pointer.
A String Object
data
len
H e l l o n
41OOP in C++Jan 2014
Members as Objects
 Sometimes a class may have a data attribute
which is an object of a class.
 Employee class may have a member “name” whose
type is String.
 When an Employee object is initialized then
name must also be initialized.
42OOP in C++Jan 2014
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, 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
43OOP in C++Jan 2014
Class Member: Notes
 It is always a good idea to define data members as
“private”.
 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.
 May also lead to stunning consequences.
44OOP in C++Jan 2014
Const Member Functions
 Constant Member Functions
are not allowed to change
the state of the object on
which they are invoked.
 Const Functions are declared
with keyword const following
member function parameter
list.
 const must also be present
at the definition.
 Type of this pointer passed
to a const function is
const X* const this
class X {
private:
int ipriv;
public:
int ipub;
int f() const;
};
int X::f() const
{
int temp;
temp = ipriv + ipub; //accessing members OK
ipriv += temp; // cannot modify any member
ipub -= temp; // cannot modify any member
}
45OOP in C++Jan 2014
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
46OOP in C++Jan 2014
Friend Functions: Example
class String {
public :
String();
String(const char *);
String(int len);
friend String concat(String *, String *)
friend String concat(String *, char *);
friend String concat(char *, String *);
private :
char *data;
int len;
} ;
String::String(int len)
{
this->len = len;
data = new char[len+1];
data[len] = ‘0’;
}
String concat(String *left, String *right)
{
String both[left->len + right->len + 1];
strcpy(both.data, left->data);
strcat(both.data, right-> data) ;
return both;
}
String concat(char *left, String *right)
{
String both[strlen(left) + right->len +
1];
strcpy(both.data, left);
strcat(both.data, right->data);
return both;
}
47OOP in C++Jan 2014
Friends of More Than One class
class Matrix; // Forward declaration to make
// declaration of crossprod legal
class Vector {
public :
Vector(int n) ;
friend Vector prod(Matrix *pM, Vector *pV);
private :
int elements[10] ;
int n;
};
class Matrix {
public :
Matrix(int m, int n) ;
friend Vector prod(Matrix *pM, Vector *pV);
private :
int elements[10][10];
int m, n;
};
Vector prod(Matrix *pM, Vector *pV)
{
int V(pM->m);
for (i = 0; i < pM->m; i++)
for (j = 0; j < pM->n; j++)
{
v[i] += pm->elements[i][j]*
pV->elements[i];
}
}
48OOP in C++Jan 2014
Friend Members & Class
 Member of a different class
may be a friend function.
 A class may be declared as a
friend implying all member
functions of that class are
friends.
 Friend-ship is neither
commutative nor transitive.
 Friends tend to break data
hiding.
 It is best to avoid friend in
an ideal OO Design.
class Matrix;
class Vector {
public:
void Vector(int n);
Vector prod(Matrix *pM);
int elements[10];
int n;
} ;
class Matrix {
public:
void Matrix(int m, int n);
friend Vector Vector::prod(Matrix *pM);
private:
int elements[10][10];
int m, n;
} ;
49OOP in C++Jan 2014
Static Data
 A static data member is
shared by all the objects
of a class.
 Static data member may
be public or private.
 Static data member must
be initialized in a source
file.
 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; // This is a
declaration
X() { count++; }
}
X::count = 0; //Definition & Initialization
int main()
{
X a, b, c;
printf(“%d %d %d %dn”, X::count, a.count,
b.count, c.count);
}
The output will be 3 3 3 3
50OOP in C++Jan 2014
Static Data: A List
class ListNode {
public:
static ListNode *first;
private:
ListNode *next;
int data;
public:
ListNode(int x);
print();
}
List Node *ListNode::first = NULL;
ListNode::ListNode(int x) {
data = x;
next = NULL;
if (first == NULL)
first = this;
else
{
next = first;
first = this;
}
}
void ListNode::print() {
ListNode *x;
x = ListNode::first;
while (x != NULL)
{
printf(“%d “, x->data);
x = x->next;
}
printf(“n”);
}
int main() {
ListNode x(5);
ListNode x(7);
ListNode x(8);
x.print();
}
The output will be 8 7 5
51OOP in C++Jan 2014
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.static_function (args);
 this pointer is not passed to a static
function
 must not refer to non-static members of
its “invoking object”
 Philosophy of static members.
52OOP in C++Jan 2014
Static Members in Inline
Functions
 Not Safe
X.hxx
Class X
{
public:
static void f();
static String g();
private:
static String s;
}
inline String X::g()
{
// do some operation on s
return s;
}
X.cxx
#include “X.hxx”
void X::f()
{
X::g();
}
The above code will not fail;
The code in the following
may fail however.
X1.cxx
#include “X.hxx”
int main()
{
X::g();
}
Data members are
guaranteed to be
initialized before any non-
inline function is called.
53OOP in C++Jan 2014
OPERATOR OVERLOADING
Object Oriented Programming in C++
Jan 2014 54OOP in C++
Overloading Operators
 Semantics of an operator is
represented by a function named
operator op, where op is an operator
symbol (+,*, - , [ ], etc. )
 These functions can either be
implemented as global friend functions
and/or methods.
55OOP in C++Jan 2014
Overloading Operators
 Example
 Let ‘+’ denote concatenation for Strings.
 “s1 + s2” denote concatenation of strings s1
and s2.
 An expression of the form “s1+s2” is
converted to s1.operator+(s2) if there is a
function named “operator+” defined in the
class String.
 “s1+s2” is also equivalent to operator+(s1,
s2) if a global function named “operator+” is
properly defined; typically such global
functions are friends to the class String.
56OOP in C++Jan 2014
Example of overloading
operator +
/ * string .h * /
const int max_string_length = 128 ;
class String {
public :
String operator + (char *text) ;
String operator + (String &s1) ;
String (char *data);
String () { data = NULL; len = 0; }
private :
char *data;
int len;
} ;
String operator+(char * text)
{
char *save = new char[len+1];
strcpy(save, data);
data = new char[len +strlen(text)
+ 1];
strcpy(data, save);
stcat(data, text);
delete[]save;
return (*this);
}
57OOP in C++Jan 2014
Overloading Assignment
Operator
String & String: :operator=( char *rhs)
{
data = new char [strlen(rhs) + 1];
strcpy ( data, rhs);
return *this ;
}
Bug:
 Memory Leak as previous
data of this is not
deleted.
.
.
.
String String: :operator=( String &rhs)
{
data = new char [rhs.len + 1];
strcpy ( data, rhs.data);
return *this ;
}
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 &
58OOP in C++Jan 2014
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) .
59OOP in C++Jan 2014
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;
}
Problem: Returning
reference to a local
object. The code fails.
Integer & operator*(Integer &lhs,
Integer &rhs)
{
Integer *result = new
Integer( lhs.data * rhd.data);
return *result;
}
Who deletes?
The caller.
What about the following
use?
Integer a(1), b(2), c(3),
d(3);
Integer e =
a*b*c*d;
60OOP in C++Jan 2014
More On “=” Operator
Overloading
 There is a system defined implementation of
assignment operator. In absence of user defined
assignment operator function, systems’ function is
used.
 System defined function makes a shallow copy.
 Some times shallow copying may be dangerous
 If the constructor uses new, assignment operator
may have to be overloaded.
 If there is a need to define a copy constructor then
there must be a need to overload assignment
operator and vice-versa.
61OOP in C++Jan 2014
Overloading Unary Operators
 Typically methods implementing unary
operators will not have any argument.
 Exceptions:
 post increment and post decrement operators.
 As there are two operators with the same symbol “+
+”, the name of the function is the the same.
 Prototype for pre increment function:
 void operator ++ ( );
 Prototype for post increment function:
 void operator ++ (int a);
62OOP in C++Jan 2014
Operator Overloading Facts
 Some operators can not be implemented as
global(friend) functions.
 =, [] etc.
 Some Operators cannot be overloaded
 ::,.*.?:,., sizeof() etc.
 Precedence or arity of an operator cannot be
changed by overloading an operator.
 Conditional Operators like &&, ||, comma
operator should not be overloaded.
63OOP in C++Jan 2014
Friends Vs Methods
 Members are better in terms of restriction of
scope which results in efficient searching for
best function to resolve overloading.
 Members will not help if the left hand side of the
operator is not of the class type.
 String s1 = “abc” + s2; // may be wrong
 In case of overloading stream operators, we
need friend due to the reason stated above.
 Resolving in case of a conflict between friend
and method.
64OOP in C++Jan 2014
Returning const from a function
 Consider the following definition
const Rational & operator * (const Rational & lhs,
const Rational & rhs);
 If the function returns a non-const, the
following is valid.
Rational a, b, c;
(a * b) = c;
 Retuning const ensures that overloaded “*” is
compatible with the same operator on built-in
types.
Jan 2014 OOP in C++ 65
Overloading using const
Class String {
public:
char & operator [ ] (int pos)
{ return data[pos]; }
const char & operator [ ] (int pos)
{ return data[pos]; }
private:
char * data;
……
}
String s1 = “Hello”;
cout << s[0]; // fine
s[0] = ‘x’; // fine
const String cs = “World”;
cout << s[0]; // fine
s[0] = ‘x’; // Error!!!
Jan 2014 OOP in C++ 66
Bit-wise const vs. Conceptual
const
 What should a constant member
function preserve?
 Bit-wise const-ness
 Conceptual const-ness
 Bit-wise const member functions may
become unsafe.
 Conceptual const member function may
need to change some bits of the object
 mutable keyword.
Jan 2014 OOP in C++ 67
INHERITANCE
Object-Oriented Programming in C++
Jan 2014 OOP in C++ 68
Topics
 Fundamentals of Inheritance
 protected Access Specifier
 Initialization
 Virtual Functions 
Jan 2014 69OOP in C++
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 2014 70OOP in C++
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.
 All (?) data members and methods of the base
class are immediately available to the derived
class.
 Thus, 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 2014 71OOP in C++
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, 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, private members of the base class
are not directly accessible to the members in
the derived class.
Jan 2014 72OOP in C++
Assume the following
class hierarchy
class C: public B
{ .. };
class B: public A
{ .. };
class A
{ .. };
Object Layout in Inheritance
Layout for an object
of type C
A-Part Data Member
B-Part Data Member
C-Part Data Member
Jan 2014 73OOP in C++
protected Members
 private data members of the base class
cannot be directly accessed by the
methods of the derived class.
 However, 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.
Jan 2014 74OOP in C++
Syntax of Inheritance
 An example
class Employee {
protected:
float basic;
long id;
public:
Employee(long id);
float getSalary();
};
class Manager : public Employee {
protected:
Employee *supervised[10];
int numberOfPeopleManaged;
public:
Manager(Id, n);
float getSalary();
void printSupervisedEmployeeId();
}
Jan 2014 75OOP in C++
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 derived class calls an
appropriate constructor of the base class
 Therefore, the constructor of the base class is
executed first and then the constructor of the
derived class is executed.
Jan 2014 76OOP in C++
Example of Derived Class
Constructor
Employee::Employee(long id)
{
this->id = id;
}
Manager::Manager(long id, int n) : Employee(id)
{
numberOfPeopleManaged = n;
}
Jan 2014 77OOP in C++
Order of Destructor Calls
 The destructor of the derived class is
responsible for cleaning up the state of
the derived object.
 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, the destructor of the base
class is executed first and then the
destructor of the derived class is
executed.
Jan 2014 78OOP in C++
Casting
 Derived class pointer can be implicitly
cast to a base class pointer
Manager m;
Employee *e = &m; // Employee *e = (Employee *)(&m);
 Only base class part of the derived object
can be seen through the base pointer.
e-> printSupervisedEmployeeId(); //error
Jan 2014 79OOP in C++
Casting
 A Base class pointer cannot be implicitly
cast to a derived class pointer
Manager *pM; pM = e; //error
pM = (Manager *)e; //ok
Down casting may be dangerous
Jan 2014 80OOP in C++
Static vs. Dynamic Binding
 Binding refers to associate a type to a
name.
 Consider the following example:
Manager m; Employee *e = &m;
e->getSalary(); //Which getSalary? Employee or Manager?
 “e” is declared as a pointer to Employee
Jan 2014 81OOP in C++
Static vs. Dynamic Binding
 Continue on the example:
Manager m; Employee *e = &m;
e->getSalary(); //Which getSalary? Employee or Manager?
 In the example however, it makes more sense to
mean “getSalary” of the Manager class.
 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 2014 82OOP in C++
Virtual Functions
 In C++, dynamic binding is made
possible only for pointer & reference
data types and for methods that are
declared as virtual in the base class.
 If a method is declared as virtual, it
can be overridden in the derived class.
 If a method is not virtual and it is re-
defined in the derived class then the
latter definition hides the former one.
Jan 2014 83OOP in C++
Virtual Function: Example
class X{ class Y: public X{
public: public:
int f(){ return 2; } int f(){ return 4;}
virtual int g(){ return 3;} int g(){ return 6;}
}; };
main() {
Y a;
int i, j , k, m;
X *b = &a;
i = b->f(); j = a.f();
k = b->g(); m = a.g();
printf(“%d %d %d %dn”, i, j, k, m);
}
Jan 2014 84OOP in C++
Output will be 2 4 6 6
Redefining a Non-Virtual
Function
 Simply do not do that.
class X() { class Y : public X {
protected: protected:
void f(); void f();
}; };
int main() {
Y y1;
Y *pY; X *pX;
pX = &y1;
pX->f(); // f as defined in X will be called
pY = &y1;
pY->f(); // f as defined in Y will be called
}
Jan 2014 85OOP in C++
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.
 During object creation,
the actual address of the
function is assigned to
the function pointer.
 Y is derived from X,
which has a virtual
function.
X-part-data
X-part-virtual-function-ptr
Y-part-data
Actual definition of
the virtual function
Jan 2014 86OOP in C++
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.
 Definition of such a class is incomplete.
 A class with one or more pure virtual function is
called an abstract class.
 Abstract class cannot be instantiated.
 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.
Jan 2014 87OOP in C++
Virtual Destructor
 Constructors cannot be virtual
 For a base class which has been derived from,
the destructor must be declared virtual.
 Occasionally we create a derived object and store
it using a pointer to Base class such as
 Base *pBase = new Derived(/*arguments*/);
 If we destroy this object using “delete pBase”
then two destructors need to be called.
 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 2014 88OOP in C++
Inheritance Example:
Polymorphic Array
 Consider an abstract base class Shape which
contains a pure virtual function “CalculateArea”.
 Suppose three classes Triangle, Rectangle and
Circle derived from Shape.
 Consider a main function that creates different
Shape objects and store them in an array.
 If in a for loop the function calculateArea is
called on all objects in the array, we see
dynamic binding in use.
Jan 2014 89OOP in C++
Polymorphic Array: Class
Definitions
class Shape {
public:
virtual double calculateArea() =
0;
};
class triangle : public Shape() {
private:
Point a, b, c;
Triangle(double x_a, double y_a,
double x_b, double y_b,
double x_c, double y_c);
public:
double calculateArea();
};
class Circle : public Shape() {
private:
Point centre;
double radius;
Circle(double x_centre,
double y_centre,
double r);,
public:
double calculateArea();
};
Jan 2014 90OOP in C++
Polymorphic Array: main
function
int main() {
Shape *pArr = NULL;
int n = getInput(pArr);
for (int i = 0; i < n; i++) {
double area =
Shape[i]->calculateArea();
printf (“%d %lf n”, i, area);
}
}
int getInput(Shape *pArr) {
printf(“Which Shape do you want to
create?n”);
printf(“Write 1 for triangle, 2 for
rectangle, 3 for circle and 0 to
quitn”);
int i,
double x_a, x_b, x_c, y_a, y_b, y_c;
while (1) { int j = 0;
scanf(“%d”, &i);
switch (i) {
case 0: break;
case 1:
scanf(“%f%f%f%f%f%f”, &x_a,
&y_a, &x_b, &y_b, &x_c, &y_c);
pArr[j++] = new Triangle(&x_a,
&y_a, &x_b, &y_b, &x_c, &y_c);
break;
……..
}
}
}
Jan 2014 91OOP in C++
Inheritance: Benefits
 Code Sharing/Reuse
 Consistency of Interface
 Construction of Software Components
 Rapid Prototyping
 Information Hiding
Jan 2014 92OOP in C++
Inheritance: Cost
 Execution Speed
 Program Size
 Message Passing Overhead
 Program Complexity
Jan 2014 93OOP in C++
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 2014 94OOP in C++
Inheritance Notes
 Constructors cannot be virtual
 Calling a virtual function from within a
constructor does not have the desired effect.
 The following code is buggy. Tell why.
void f(Base *b) { int main() {
b[0].f(); b[1].f(); Derived d[10];
} f(d);
}
 Derived is publicly derived from Base.
 Class Base has a virtual function “f” which is
redefined in Derived.
Jan 2014 95OOP in C++
Default Parameter & Virtual
Function
 Do not change the default parameter in a
redefined virtual function
class X() { class Y : public X {
protected: protected:
virtual void f(int i = 10); virtual void f(int i =20);
}; };
int main() {
Y y1;
Y *pY; X *pX;
pX = &y1;
pX->f(); // f with value of i as 10 will be called
pY = &y1;
pY->f(); // f with value of i as 20 will be called
}
Jan 2014 96OOP in C++
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.
 fly method has to be redefined as an
empty function.
 Leads to a logical dilemma.
 Can an overridden method be empty?
 Can an overridden method throw
exceptions?
Jan 2014 97OOP in C++
Is a Circle an Ellipse?
 Circle is a special type of ellipse.
 Let Circle be derived from Ellipse.
 Suppose that Ellipse has a method
setSize(x,y).
 Also suppose that there is a function sample as
defined below.
sample (Ellipse &e) { e. setSize(10,20); ……. }
 If sample is called on a circle, strange things
happen!
 Subset is not substitutable!!
Jan 2014 98OOP in C++
Should a Stack inherit from a
List?
 Probably Not!
 If List is the base class of Stack
 Methods such as push, pop etc. 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.
 A Stack has a List.
Jan 2014 99OOP in C++
Multi-level Inheritance
 Suppose that C is derived from B and B is
derived from A.
 Suppose that a method, f, in A is virtual.
 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.
 It is advisable to explicitly write “virtual” in
front of the definition of f in B as, otherwise,
an implementer of C may think that f is not a
virtual method.
Jan 2014 100OOP in C++
Inheritance & Code Reuse
 Suppose that C and B and are derived from A.
 Both C and B contain a function f ; therefore, f
is made a virtual (not pure) function in A.
 This is bad.
 A new class D is required to be derived from A
later.
 f in D is different than A.
 Interfaces should not have implementation.
Jan 2014 101OOP in C++
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 2014 102OOP 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 2014 103OOP in C++
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 2014 104OOP in C++
TYPE CASTING
Object-Oriented Programming in C++
Jan 2014 OOP in C++ 105
Type Casting
 Why casting?
 Casts are used to convert the type of an object,
expression, function argument, or return value to
that of another type.
 (Silent) Implicit conversions.
 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 2014 OOP in C++ 106
Type Casting
To perform a type cast, the compiler
 allocates temporary storage
 Initializes temporary with value being cast
float f (int i,int j) {
return (float ) i / j;
}
// compiler generates:
float f (int i, int j) {
float temp_I = i, temp_j = j;
return temp_i / temp_j;
}
107OOP in C++Jan 2014
Automatic (Implicit) Conversion
 Automatic conversions from one type to
other may be extremely convenient.
 Automatic conversions (either
conversion operators or single argument
non-explicit constructors) are unsafe as
well.
 can interfere with overload resolutions.
 can silently let wrong code compile cleanly.
String s1, s2, s3;
s3 = s2 – s1; // Though “-” is not overloaded in String
Jan 2014 OOP in C++ 108
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; s1 = “example”;
109OOP in C++Jan 2014
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”;
110OOP in C++Jan 2014
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;
}
111OOP in C++Jan 2014
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
112OOP in C++Jan 2014
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 *()” .
113OOP in C++Jan 2014
Example of user defined cast
const int max_string_length = 128;
class String {
public:
String ( ) :
String (const String & ) ;
String (const char *);
~String ( ) ;
String & operator = (const String & )
;
operator const char * ( ) const ;
int length ( ) const ;
int read ( ) ;
void print ( ) const ;
.
.
private:
char text [max_string_length+1]
};
void operator-(const String &, const
String &);
int main ( ) {
int fd;
String filename = “tmp/test”;
// cast filename to type const char *
fd = open (filename, O_WRONLY |
O_CREAT, 0666);
write (fd, “test”, 4);
close (fd);
// not legal, since we can cast only
to const char *
// strcpy (filename, “zbc”);
String name = “Zaphod
Beeblebrox”;
name – “Beeblebrox”; // is now
ambiguous.
return 0 ;
}
114OOP in C++Jan 2014
Avoiding Ambiguities
const int max_string_length = 128;
class String {
public:
String ( ) ;
String (const String & ) ;
String (const char *);
~ String ( ) ;
String & operator = (const String
& );
const char *as_char_pointer ( )
const;
int length ( ) const;
int read ( );
void print ( ) const;
...
private:
char text [max_string_length+1];
};
void operator-(const String &, const
String &);
int main ( ) {
int fd;
String filename = “/tmp/test”;
// convert filename to type char *
fd = open
(filename.as_char_pointer ( ),
O_WRONLY | O_CREAT, 0666);
write (fd, “test”, 4);
close (fd);
// not legal
// strcpy (filename.as_char_pointer (
), “zbc”);
String name = “Zaphod
Beeblebrox”;
name – “Beeblebrox”; // is no longer
ambiguous
return 0;
}
115OOP in C++Jan 2014
Casting Pointers & References
 Casting a value:
 float f_var = 3.14;
 cout << (int) f_var;
 creates a temporary object
 does not violate data encapsulation
 Casting a pointer or reference
 cout << *(( int *) &f_var);
 cout << (int &) f_var;
 Re-interprets representation of object
 Violates data encapsulation
116OOP in C++Jan 2014
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
117OOP in C++Jan 2014
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.
 More narrowly specified purpose for each
specified cast; compilers can diagnose user
errors.
 Some casts are performed safely at run-time.
Jan 2014 OOP in C++ 118
const_cast operator
 Syntax:
 const_cast < type-id > ( expression )
 The const_cast operator can be used to remove the
const, 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, volatile
qualifiers. Applying on pointers and references, the
result will refer to the original object.
 The const_cast operator cannot be used to directly
override a constant variable's constant status.
Jan 2014 OOP in C++ 119
const_cast operator: Example
Example
#include <iostream>
class CCTest {
public:
void setNumber( int );
void printNumber() const;
private:
int number;
};
void CCTest::setNumber( int num )
{ number = num; }
void CCTest::printNumber() const {
cout << "nBefore: " << number;
const_cast< CCTest * >( this )-
>number--;
cout << "nAfter: " << number;
}
int main() {
CCTest X;
X.setNumber( 8 );
X.printNumber();
}
 On the line containing the
const_cast, the data type of
the this pointer is const CCTest
*. The const_cast operator
changes the data type of the
this pointer to CCTest *,
allowing the member “number”
to be modified. The cast lasts
only for the remainder of the
line on which it appears.
Jan 2014 120OOP in C++
Usage of “const”
 The example of the previous slide is not
the best usage of const.
 The member “number” should be “mutable”
instead.
 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 2014 121OOP in C++
Guidelines for const
 const is a powerful tool for writing safer code;
use it as much as possible but no more.
 Do not use const pass-by-value parameters in
function declarations. This is not useful and
misleading at best.
 When returning a user defined type, prefer
returning a const value.
 Do not return handles to internal data from a
const member function.
Jan 2014 OOP in C++ 122
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, meaning
and restrictions as C-style cast. It cannot be
used to convert a struct into an int or a double
into a pointer.
Jan 2014 OOP in C++ 123
static_cast operator
 In general, a complete type can be converted
to another type so long as some conversion
sequence is provided by the language.
 may also use static_cast to convert any
expression to a void, in which case the value of
the expression is discarded.
 It cannot change the const-ness of an
expression.
Jan 2014 OOP in C++ 124
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
...
}.
static_cast: Example
 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 run-
time type check is made
to ensure the safety of
the conversion.For such
conversions dynamic_cast
should be used.
Jan 2014 125OOP 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 2014 OOP in C++ 126
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 2014 127OOP in C++
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, non-portable.
 The reinterpret_cast operator cannot cast away the
const, volatile attributes.
 One practical use of reinterpret_cast is in a hash
function, which maps a value to an index in such a way
that two distinct values rarely end up with the same
index.
 Reinterpret_cast should rarely be used in a C++
program
Jan 2014 OOP in C++ 128
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 );
return ( unsigned short )( val ^ (val
>> 16));
}
int main(){
int a[20];
for ( int i = 0; i < 20; i++ )
cout << Hash( a + i ) << endl;
}
 The reinterpret_cast
allows the pointer to be
treated as an integral
type. The result is then
bit-shifted and XORed
with itself to produce a
unique index (unique to
a high degree of
probability). The index is
then truncated by a
standard C-style cast to
the return type of the
function.
Jan 2014 129OOP in C++
Usage of casts
class A { public: virtual ~A(); …};
class B : private virtual A { …};
class C : public A { … };
class D : public B, public C { …};
A a1; B b1; C c1; D d1;
const A a2;
const A& ra1 = a1;
const A& ra2 = a2;
char c;
 A *pa = (A *)&ra1;
 Use const_cast
 B * pb = (B*)&c1;
 Use reinterpret_cast
 A *pa = (A*)&a2;
 Cannot be expressed
in a new-style cast.
 void *pv = &b1;
 B *pb = (B*)(pv);
 Use static_cast
instead;
Jan 2014 OOP in C++ 130
Avoid Unnecessary Cast
 Look at the cast and comment
class SpecialWindow: public Window { // derived class
public:
virtual void onResize() { // derived onResize impl;
static_cast<Window>(*this).onResize(); // cast *this to Window,
// then call its onResize;
// this doesn’t work!
... // do SpecialWindow-
} // specific stuff
...
};
Jan 2014 OOP in C++ 131
type_info class
 The type_info class describes type information
generated within the program by the compiler. The
entire definition of this class is implementation
dependent but the following features of this class is
standardized.
 Objects of this class effectively store a pointer to a
name for the type. The type_info class also stores an
encoded value suitable for comparing two types for
equality or collating order.
 The operators “==“ and “!=“ are overloaded and can
be used to compare for equality and inequality with
other type_info objects, respectively.
Jan 2014 OOP in C++ 132
type_info class
 Features of type_info class (contd):
 The “name” member function returns a const char*
to a null-terminated string representing the human-
readable name of the type. The memory pointed to is
cached and should never be directly deallocated.
 Type information is generated for polymorphic
classes only if the /GR (Enable Run-Time Type
Information) compiler option is specified.
Jan 2014 OOP in C++ 133
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 result of typeid is a const type_info&.
 The typeid operator does a run-time check when
applied to an l-value of a polymorphic class
type, where the true type of the object cannot
be determined by the static information
provided. Such cases are: a reference/ Pointer
134OOP in C++Jan 2014
typeid operator
 When the operand of typeid is of a non-
polymorphic class type, the result is the type of
the operand not the type of the underlying
object.
 type-id may be used with operands of built-in
types.
135OOP in C++Jan 2014
 The expression usually
points to a polymorphic
type (a class with virtual
functions).
 The pointer must be de-
referenced so that the
object it points to is used.
Without de-referencing the
pointer, the result will be
the type_info for the
pointer, not pointee
Example
#include <iostream>
#include <typeinfo.h>
class Base {
public: virtual void vvfunc()
{} }
class Derived : public Base {};
typeid:Example
int main(){
Derived* pd = new Derived;
Base* pb = pd;
cout << typeid( pb ).name() << endl;
//prints "class Base *”
cout << typeid( *pb ).name() <<
endl; //prints "class Derived"
cout << typeid( pd ).name() << endl;
//prints "class Derived *"
cout << typeid( *pd ).name() <<
endl; //prints "class Derived"
delete pd;
}
136OOP in C++Jan 2014
dynamic_cast operator
 Syntax:
 dynamic_cast<type-
id> (expression)
 The expression
dynamic_cast<type-
id>( expression)
converts the operand
expression to an
object of type type-
id.
 It is used for down-
casting.
Example
class B { ... };
class C : public B { ... };
class D : public C { ... };
void f(D* pd){
C* pc = dynamic_cast<C*>(pd);
// ok: C is a direct base class, pc
points to C subobject of pd
B* pb = dynamic_cast<B*>(pd);
// ok: B is an indirect base
class , pb points to B subobject of pd
...
}
137OOP in C++Jan 2014
dynamic_cast: Example
Example:
class B { ... };
class D : public B { ... };
void f(){
B* pb = new D; // unclear but ok
B* pb2 = new B;
D* pd = dynamic_cast<D*>(pb); // ok: pb actually points to a D
...
D* pd2 = dynamic_cast<D*>(pb2); // pb2 points to a B not a D the cast is bad
so pd2 is NULL
...
}
138OOP in C++Jan 2014
dynamic_cast
 If dynamic_cast to a pointer type fails, the result of the
dynamic_cast is null; if dynamic_cast to a reference type
fails, an exception is thrown.
 dynamic_cast is performed at run-time.
 dynamic_cast can be used only for pointer or reference
types to navigate a class hierarchy. The dynamic_cast
operator can be used to cast from a derived class pointer
to a base class pointer, cast a derived class pointer to
another derived (sibling) class pointer, or cast a base
class pointer to a derived class pointer. Each of these
conversions may also be applied to references.
139OOP in C++Jan 2014
dynamic_cast
 dynamic_cast operator cannot be used for built-in types.
 All of the derived-to-base conversions are performed
using the static (compile-time) type information. These
conversions may, therefore, be performed on both non-
polymorphic and polymorphic types. These conversions
will produce the same result if they are converted using a
static_cast. However, even these results may be wrong in
the presence of multiple inheritance.
 dynamic_cast is strongly recommended to be applied on
polymorphic types.
140OOP in C++Jan 2014
Cost of dynamic_cast
 The pointer to the type_info object of a class is
stored in the vtbl array of the class.
 Thus, 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.
 Size of the objects do not increase for RTTI
operations.
 Cost of RTTI at run time is similar to the cost of
calling a virtual function; cost of calling a
virtual function is the same as the cost of
calling a function through a function pointer.
141OOP in C++Jan 2014
EXCEPTIONS
Object Oriented Programming in C++
Jan 2014 142OOP in C++
Topics
 Basic Concept of Exceptions
 try-catch block in C++
 Semantics of throw
Jan 2014 143OOP in C++
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.
Jan 2014 144OOP in C++
Error Handling in C++
 Error Condition Handling - C++
Style
 On error condition an exception object
is created and thrown.
 A function catches exception objects
generated from the function it calls in
a distinct control flow.
 Similar Exception objects can enjoy
benefits of inheritance.
Jan 2014 145OOP in C++
C-Style Error Handling
int
Calculator::divide (int i)
{
if (i == 0)
{
// what do we do?
}
else
{
value /= i;
}
return value;
}
 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 2014 146OOP in C++
“try” and “catch”
 A function has its usual prototype and it may
throw a number of exceptions on detecting
several error condition.
 “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 2014 147OOP in C++
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, a
suitable Exception object is thrown. Semantics
of throw is as follows.
 Creation of an object (function of new)
 passing control from this function to the caller
function (similar to return)
 Unlike return, throw initiates unwinding of the call
stack till the exception is handled.
Jan 2014 148OOP in C++
Example of Exception Handling
in C++
class DivideByZero {
private:
int dividend;
public:
print() {
cout << dividend << “is divided by zero”
<<endl;
}
DivideByZero(int d) { dividend = d; }
};
int Calculator::divide(int i) throws DivideByZero
{
if (i ==0)
throw DivideByZero(value);
value /= i;
return value;
}
int main (int argc, char **argv) {
int i = 0;
Calculator c;
try {
c.divide (0);
cout << c.getValue ();
}
catch (DivideByZero& ext) {
ex.print();
return 1;
}
return 0;
}
Jan 2014 149OOP in C++
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.
 Control passes to first matching catch block
 Can handle the exception and continue
 Can free resources and re-throw
Jan 2014 150OOP in C++
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.
 catch blocks after a try block are examined in
order when an exception is thrown from a
function called in the try block.
 Parentheses for each catch block has semantics
of a “function argument declaration”
Jan 2014 151OOP in C++
Exception Specifications
// can throw anything
void
Calculator::subtract
(int i);
// promises not to throw
void
Calculator::add
(int i) throw ();
// promises to only throw int
void
Calculator::divide
(int i) throw (int);
 Make promises to the caller
 Allow stronger type checking
enforced by the compiler
 By default, 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
 A throw clause with no types
 Promises nothing will be thrown
 Can list multiple types
 Comma separated
Jan 2014 152OOP in C++
Stack Frame
 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 run-
time. Contains:
 The frame pointer
 The return address for the call (i.e., where
it was called from)
 Parameters passed to the function
 Automatic (stack) variables for the function
previous frame pointer
return address
parameters
automatic variables
Jan 2014 153OOP in C++
Illustrating the Call Stack
int main (int argc, char **argv) {
int i = 0;
Calculator c;
try {
c.divide (0);
cout <<
c.get_value ();
}
catch (int) {
return 1;
}
return 0;
}
 Stack frame for function main
 Pushed on program call stack
 With stack variables i and c
 With parameters argc and argv
 Note that parameters are
initialized at frame creation
 Variables are not necessarily
initialized at frame creation
 May occur later in called
function
argc argv
i c value_
main
Jan 2014 154OOP in C++
Illustrating the Call Stack, cont.
int main (int argc, char **argv) {
int i = 0;
Calculator c;
try {
c.divide (0);
cout <<
c.get_value ();
}
catch (int) {
return 1;
}
return 0;
}
 Enter function main
 Stack variable initialized to
0
argc argv
i c value_
main
Jan 2014 155OOP in C++
Illustrating the Call Stack, cont.
int main (int argc, char **argv) {
int i = 0;
Calculator c;
try {
c.divide (0);
cout <<
c.get_value ();
}
catch (int) {
return 1;
}
return 0;
}
 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
argc argv
i c value_
main
Calculator::
Calculator( ) this
Jan 2014 156OOP in C++
Illustrating the Call Stack, cont.
Calculator::Calculator ()
: value_ (0)
{}
void
Calculator::divide (int i) throw (int)
{
if (i == 0) {
throw i;
} else {
value_ /= i;
}
cout << value_;
}
 Enter function Calculator::Calculator ( )
 Member variable value_ of stack variable c
is initialized to zero
 How do we know which value_ to set?
 There may be multiple Calculator instances
 Answer: implicit “this” parameter in stack
frame
argc argv
i c value_
main
Calculator::
Calculator() this
Jan 2014 157OOP in C++
Illustrating the Call Stack, cont.
Calculator::Calculator ()
: value_ (0)
{
}
void
Calculator::divide (int i) throw
(int) {
if (i == 0) {
throw i;
} else {
value_ /= i;
}
cout << value_;
}
 Return from function
Calculator::Calculator ( )
 Pop the stack frame, return to
previous
argc argv
i c value_main
Jan 2014 158OOP in C++
Illustrating the Call Stack, cont.
int main (int argc, char **argv)
{
int i = 0;
Calculator c;
try {
c.divide (0);
cout <<
c.get_value ();
}
catch (int) {
return 1;
}
return 0;
}
 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
void Calculator::
divide (int )
main
argc argv
i c value_
this i
Jan 2014 159OOP in C++
Illustrating the Call Stack, cont.
 Enter function Calculator::divide
(int)
 Test i equal to 0 and take the true
branch
 Throw integer i
main
void Calculator::
Calculator (int )
argc argv
i c value_
this i
Calculator::Calculator ()
: value_ (0)
{
}
void
Calculator::divide (int i) throw (int)
{
if (i == 0) {
throw i;
} else {
value_ /= i;
}
cout << value_;
}
Jan 2014 160OOP in C++
Illustrating the Call Stack, cont.
Calculator::Calculator ()
: value_ (0)
{
}
void
Calculator::divide (int i) throw
(int)
{
if (i == 0) {
throw i;
} else {
value_ /= i;
}
cout << value_;
}
 Thrown exception unwinds call stack
 Notice control skips over cout statement
to end
 Pop the stack frame, return to previous
 Return from function void
Calculator::divide ( )
argc argv
i c value_
main
Jan 2014 161OOP in C++
Illustrating the Call Stack, cont.
int main (int argc, char **argv)
{
int i = 0;
Calculator c;
try
{
c.divide (0);
cout << c.get_value ();
}
catch (int)
{
return 1;
}
return 0;
}
 We’ve reached an enclosing
try/catch scope
 So stack unwinding stops
 Control jumps to first matching
catch block
 Again, skips over intervening cout
statement
argc argv
i c value_
main
Jan 2014 162OOP in C++
More on catch
try {
// can throw an exception
}
catch (Derived &d) {
// ...
}
catch (Base &b) {
// ...
}
catch (...) // catch all...
{
// ...
}
 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
Jan 2014 163OOP in C++
A Few More on catch
try
{
// can throw an exception
}
catch (MyClass &e)
{
// ...
throw; // rethrows e
}
catch (int)
{
// ...
}
catch (...) // catch all...
{
// ...
}
 Notice catch-by-reference
for user defined types
 More efficient
 Only a reference propagates
 Rather than entire object
 More correct
 Avoids class-slicing problem
if catch as base type, rethrow
 Preserves polymorphism
 More on this in later lectures
 Can leave off variable
name
 Unless catch block needs
to do something with the
instance that was caught
Jan 2014 164OOP in C++
TEMPLATES
Object-Oriented Programming in C++
Jan 2014 OOP in C++ 165
What is a Template?
 Templates are specifications of a
collection of functions or classes which
are parameterized by types.
 Examples:
 Function search, min etc..
 The basic algorithms in these functions are the same
independent of types.
 But, we need to write different versions of these
functions for strong type checking in C++.
 Classes list, queue etc.
 The data members and the methods are almost the
same for list of numbers, list of objects.
 We need to define different classes, however.
Jan 2014 166OOP in C++
template<class X> void swap (X &one, X
&other)
{
X temp;
temp = one;
one = other;
other = temp;
}
Main() {
int I=10, j=20;
swap(I, j);
String s1(“abc”), s2(“def”);
swap(s1, s2);
}
Function Template: An Example
void swap(int &i, int &j)
{
int temp;
temp = i;
i = j;
j = temp;
}
void swap(String &i, String &j)
{
String temp;
temp = i;
i = j;
j = temp;
}
Type parameter
Type parameter list
Template instantiation
Jan 2014 167OOP in C++
Parameterized Functions
 A function template
 describes how a function should be built
 supplies the definition of the function using some
arbitrary types, (as place holders),
 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 class, (i.e. type), parameters
Jan 2014 168OOP in C++
Template Non-type Parameter
 It is an ordinary parameter
 template <class T, int size> T min (T
(&x[size]));
 When min is called, size is replaced with
a constant value known at compile time
 The actual value for a non-type
parameter must be a constant
expression.
Jan 2014 169OOP in C++
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 2014 170OOP in C++
Template Argument Deduction
 Each item in the template parameter list is a
template argument
 When a template function is invoked, the
values of the template arguments are
determined by seeing the types of the function
arguments
template <class T, int size> Type min( T(&x[size]));
int pval[9]; min(pval); //Error!!
Jan 2014 171OOP in C++
Template Argument Deduction
 Three kinds of conversions are allowed.
 L-value transformation (e.g., 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 2014 172OOP in C++
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, T y);
 unsigned int ui; min (ui, 1024); //Error!!
 min<unsigned int>(ui, 1024); // OK
 Specifying return type generically is often a
problem.
 template <class T, class U> ??? sum(T x, U y);
 sum(ch, ui) returns U; sum (ui, ch) returns T
 template < class R, class T, class U> R sum(T x, U
y)
 min<int>(i, ‘a’);
Jan 2014 173OOP in C++
Template Explicit Specialization
 Some times, a template may not be
suitable for all types.
 The following template is not good for
char *
template <class T> T min(T x, T y)
{ return (x < y) ? x : y); }
 Define the function explicitly for char *
template<> char * min <char *>(char *x, char *y)
{ return ((strcmp(x, y) < 0) ? x : y); }
Jan 2014 174OOP in C++
A List Template Class
template<class T>
class List {
public :
List ();
virtual ~List ();
int put (const T &val);
T *unput ();
T *get ();
int unget (const T &val);
T *find(const T &val);
int length ();
private:
struct Node {
Node *next_item;
T *list_item;
} *beg_ptr; *end_ptr;
int how_many;
};
template<class T> int List<T>:: put (const T
&val)
{
Node *tmp_ptr = new Node;
if (tmp_ptr && (tmp_ptr->list_item = new
T (val) ) ) {
tmp_ptr->next_item = 0;
if (end_ptr)
end_ptr->next_item = tmp_ptr;
else
beg_ptr = tmp_ptr;
end_ptr = tmp_ptr;
how_many++;
return 1;
}
else
return 0;
}
Jan 2014 175OOP in C++
Using a Template Class
int main () {
register int i, *iptr;
String *sptr;
char *somedata [] = {“one”, “two”, “three”, “four”,
“five”, “six”, “seven”, “eight”, “nine”, “ten”};
List<int> ii;
List<String> is;
for (i = 1; i <=10; i++) { ii.put(i); }
cout << “The List<int> contains “ ;
cout << ii.length () << “ itemsn” ;
return 0;
}
Jan 2014 176OOP in C++
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, (as a place holder).
 is a parameterized type with
parameterized member functions
Jan 2014 177OOP in C++
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, (i.e. type),
parameters
 is often used for “container” classes
Jan 2014 178OOP in C++
Parameter Requirements
Parameter Types
 may be of any type, (including user defined
types)
 may be parameterized types, (i.e. 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 ?
Jan 2014 179OOP in C++
Class Template Instantiation
 Class Template is instantiated only when it is
required.
 Matrix is a class template
 Matrix m; //error
 Matrix *pm; // OK
 void inverse (Matrix & m); //OK
 Class template is instantiated before
 An object is defined with class template instantiation
 If a pointer or a reference is de-referenced (e.g., 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 2014 180OOP in C++
Friend & Static Declaration
 There are 3 kinds of friend declarations
 Non-template friend.
 A bound friend class template.
 One-to-one mapping between the instance of a class template
and its friend
 An unbound friend class template.
 One-to-many mapping between the instance of a class
template and its friend
 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.
Jan 2014 181OOP in C++
Source code organization
 Inclusion Model
 Make the template definition visible to
compiler at the point of instantiation
 Include source files as well.
 Increase in build and link time
 Instantiate the types you need explicitly in a
separate compile unit.
 Cannot use benefits of lazy instantiation.
 Separation Model
 Use keyword ‘export’ in front of definition.
 Not many compiler supports the feature.
Jan 2014 182OOP in C++
Template specialization
 Allows to make specific implementation when
pattern is of determined type.
 The syntax is
template<> class XXX<Type> {..}
 No member is ‘inherited’ from the generic
template to specialized one. So, must define
ALL members equating them to specialization
 Class templates can be partially specialized too.
 A totally disjoint template that the compiler gives a
priority while instantiation.
Jan 2014 183OOP in C++
Templates & Derivation
 A template expresses a commonality across
types
 Two types generated from a common template are
different.
 A Base class expresses commonality of
representation and calling interface.
 Example
 template <class T, class A> class specalContainer :
public Container<T>, A;
 specialContainer<Node, Fast_Allocator> s;
 specialContainer<Node, Shared> s1;
 specialContainer<ProcessDescriptor, Fast_Allocator>
p;Jan 2014 184OOP in C++
Template Inheritance: A Base
Template
template<class T>
class set {
public :
Set ( ) { } ;
virtual void add (const T
&val);
int length ( ) ;
int find (const T &val);
private:
List<T> items;
};
template<class T>
void Set<T> : : add (const T &val)
{
if (items.find (val) ) return;
items.put (val) ;
}
template<class T>
int Set<T> : : length ( )
{
return items.length ( ) ;
}
template<class T>
int Set<T> ::find (const T &val)
{
return (int) items.find(val);
}
Jan 2014 185OOP in C++
Template Inheritance: A
Derived Template
/* boundset.h */
#include “set.h”
template<class T>
class BoundSet : public Set<T>
public:
BoundSet (const T &lower,
const T &upper);
void add(const T &val);
private:
T min;
T max;
};
template<class T>
BoundSet<T>:: BoundSet (const T
&lower, const T &upper)
: min (lower), max (upper)
{
}
template<class T>
void BoundSet<T> : :add(const T
&val)
{
if (find (val) ) return;
if ( (val <= max) && (val
>= min) )
Set<T>: : add
(val) ;
}
Jan 2014 186OOP in C++
Using a Derived Template Class
int main ( ) {
register int i ;
BoundSet<int> bsi (3, 21);
Set<int> *Setptr = &bsi;
for (i = 0; i < 25; i++)
setptr->add( i ) ;
if (bsi.find (4)
cout << “We found an expected valuen”;
if (bsi.find (0) || bsi.find(25 ) ) {
cout << “We found an Unexpected valuen”;
return 23;
}
else
cout << “We found NO unexpected valuen”;
return 0;
}
Jan 2014 187OOP in C++
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.
 Compiler view
 Constructor of objects containing virtual functions
must initialize the vptr table.
 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 2014 188OOP in C++
Inheritance vs Templates:
Example
Implement the following command.
# ECHO infile outfile
main() {
(argc > 2 ? ofstream
(argv[2] ,ios::out) : cout)
<<
(argc > 1 ? ifstream (argv[1],
ios::in) : cin)
.rdbuf();
}
main()
{
fstream in, out;
if (argc > 1) in.open(argv[1],
ios::in);
if (argc > 2) out.open(argv[2],
ios::out);
Process(in.is_open() ? in : cin,
out.is_open() ? out :
cout);
}
 How to implement ‘Process’ ?
 Two ways to get the
polymorphic behavior
 virtual function and templates
Jan 2014 189OOP in C++
Inheritance vs Templates:
Solution
template<typename In, typename
out>
void process(In& in, Out& out)
{
// out << in.rdbuf();
}
 Merely requires that
the passed objects
to have suitable
interface (such as
member function
named rdbuf(). )
void Process (basic_istream& in,
basic_ostream& out) {
// out << in.rdbuf();
}
 Requirement:
 cin and ifstream both derived
from basic_istream
 The common base class
‘basic_istream has suitable
interface ‘rdbuf’.
 Both Methods solve the current
problem.
 But templates provide
extensibility.
 Other streams can be provided
with rdbuf() interface.
 Other streams cannot be
guaranteed to be derived from
the same base class
Jan 2014 190OOP in C++
Another Example
 A collection of classes is required for
 Stack: for ints , strings, floats etc.
 Has operations: push, pop, length of stack.
 transportationMode . For airplane, car, boat etc.
 Has features : move, comfort etc
 each move in diff ways.
 Each provide different level of comfort.
 Analyze if the ‘type’ being manipulated has any
affect on the behavior of class .
 If ‘type’ does not affect the behavior, use templates
 If ‘type’ affects the behavior, use virtual functions
(inheritance)
Jan 2014 191OOP in C++
Thank You
Jan 2014 OOP in C++ 193
Ranking of Programming Languages in Jan 2014
TIOBE Index for January 2014
Jan-14 Jan-13Change Programming Language Ratings Change
1 1 = C 17.87% 0.02%
2 2 = Java 16.50% -0.92%
3 3 = Objective-C 11.10% 0.82%
4 4 = C++ 7.55% -1.59%
5 5 = C# 5.86% -0.34%
6 6 = PHP 4.63% -0.92%
7 7 = (Visual) Basic 2.99% -1.76%
8 8 = Python 2.40% -1.77%
9 10 + JavaScript 1.57% -0.41%
10 22 + Transact-SQL 1.56% 0.98%
11 12 + Visual Basic .NET 1.56% 0.52%
12 11 – Ruby 1.08% -0.69%
13 9 – Perl 0.92% -1.35%
14 14 = Pascal 0.78% -0.15%
15 17 + MATLAB 0.78% 0.14%
16 45 + F# 0.72% 0.53%
17 21 + PL/SQL 0.63% 0.05%
18 35 + D 0.63% 0.33%
19 13 – Lisp 0.60% -0.35%
20 15 – Delphi/Object Pascal 0.60% -0.32%
http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
Jan 2014 OOP in C++ 194

OOP in C++

  • 1.
  • 2.
    PROGRAMMING IN C++ Object-OrientedModeling & Programming OOP in C++ 2Jan 2014
  • 3.
    Topics  Procedural Enhancementsin C++ over C  Classes  Overloading  Inheritance  Type Casting  Exceptions  Templates 3OOP in C++Jan 2014
  • 4.
    PROCEDURAL ENHANCEMENTS IN C++ ObjectOriented Programming in C++ Jan 2014 4OOP in C++
  • 5.
    TOPICS  Const-ness  ReferenceData Type  Inline Functions  Default Function Parameters  Function Overloading & Resolution  Dynamic Memory Allocation 5OOP in C++Jan 2014
  • 6.
    const Quantifier  constqualifier transforms an object into a constant.  Example: const int capacity = 512;  Any attempt to write a const object is an error  Const object must be initialized.  Pointer to a non-constant object can not point to a const object; const double d = 5.6; double *p = &d; //error  Pointer to a constant object vs. constant pointer to an object. const double * pConstantObject; double * const *pConstantPointer; 6OOP in C++Jan 2014
  • 7.
    References  A referenceis an additional name / alias / synonym for an existing variable  Declaration of a Reference <type> & <name> = <existing variable>;  Examples of Declaration int j = 5; int& i = j; 7OOP in C++Jan 2014
  • 8.
    References  Wrong declarations int& i; // must be initialized  int& j = 5; // may be declared as const reference  int& i = j+k; // 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 8OOP in C++Jan 2014
  • 9.
    References Do not..  Cannot have an array of references  No operator other than initialization are valid on a reference.  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. 9OOP in C++Jan 2014
  • 10.
    Returning a Reference Returninga 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 10OOP in C++Jan 2014
  • 11.
    Returning a Reference #include<iostream> using namespace std; int& max(int& i, int& j) { if (i > j) return i; else return j; } int main(int, char *[]) { int x = 42, y = 7500, z; z = max(x, y) ; // z is now 7500 max(x, y) = 1 ; // y is now 1 cout << "x = " << x; cout << " y = " << y; cout << " z = " << z << "n"; return 0; } 11OOP in C++Jan 2014
  • 12.
    Pointers vs. References Pointers can point to NULL whereas References cannot. There is nothing defined as NULL Reference.  Pointers can point to different variables at different times whereas for a reference, its referent is fixed.  References make code faster since, unlike pointers, checks for NULL are not required.  Reference “refers” to an address but does not store that address. Pointer does. 12OOP in C++Jan 2014
  • 13.
    Macros  Macros areexpanded at the places of their calls.  Advantages:  Speed-wise efficient  Disadvantages:  Parameter passing mechanism is not robust and frequently leads to errors.  Type checking during parameter passing is not done  Code size tend to increase  Typical Use:  Small code re-use 13OOP in C++Jan 2014
  • 14.
    Inline Functions  Inlinefunctions act like functions  They can be class members  Type checking is performed  They can be overloaded  They obey normal parameter passing rules  But they are implemented like macros  Code is substituted inline, not called  Use is faster than calling a function  Use may take more space  They are defined in .h files, not in .c/.cxx files 14OOP in C++Jan 2014
  • 15.
    Inline Notes  inlinespecification is only a recommendation.  A recursive or a large function may not be inline.  Unlike a non-inline function, an inline function must be defined in every text file where it is called.  Inline functions must not have two different definitions.  May cause unexpected behavior if compiler does not chose to make the function inline. 15OOP in C++Jan 2014
  • 16.
    Default Function Arguments Default arguments are appropriate argument value of a parameter for a majority of cases.  Default arguments can be supplied to one or more parameters.  Default arguments may be expressions also.  All parameters to the right of a parameter with default argument must have default arguments.  Default arguments cannot be re-defined.  Default parameters should be supplied only in a header file and not in the definition of a function. 16OOP in C++Jan 2014
  • 17.
    Default Arguments: Example Following are some examples of functions with default arguments. Void ff (int, float = 0.0, char *); // Error Void ff2(int, float = 0, char *=NULL); // OK Void ff2(int float = 1, char *= NULL); // Error – Redefinition Assume that ff.h contains the following declaration ff(int, float, char = ‘a’); Wrong example: #include “ff.h” ff(int i, float f = 0.0, char ch = ‘a’); //Error However, the following are correct. #include <ff.h> ff(int i, float f = 0.0, char ch); //OK ff(int i = 0, float f, char ch); //OK 17OOP in C++Jan 2014
  • 18.
    Function Overloading  Thesame function name may be used in several definitions.  Functions with the same name must have different number of formal parameters and/or different types of formal parameters.  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 re- declare”.  Overloading allows static polymorphism 18OOP in C++Jan 2014
  • 19.
    Overload Resolution  Stepsto resolve overloaded functions with one parameter  Identify the set of candidate functions and the set of viable functions.  Select the best viable function through (Order is important)  Exact Match  Promotion  Standard type conversion  User defined type conversion 19OOP in C++Jan 2014
  • 20.
    Overload Resolution  Stepsto resolve overloaded functions with one parameter  Example: 1. void f(); 2. void f(int); 3. void f(double, double = 3.4); 4. void f(char, char *); f(5.6) Candidate function: 2 & 3 Best function: 3 20OOP in C++Jan 2014
  • 21.
    Exact Match  lvalue-to-rvalueconversion  Most common  Array-to-pointer conversion Definitions: int ar[10]; void f(int *a); Call: f(ar)  Function-to-pointer conversion Definitions: int (*fp) (int); void f(int x, fp); int g(int); Call: f(5, g)  Qualification conversion  Converting pointer (only) to const pointer. 21OOP in C++Jan 2014
  • 22.
    Promotion & Conversion Examples of Promotion  char to int; 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 22OOP in C++Jan 2014
  • 23.
    Examples of Resolution 1.Promotion enum e1 { a1, b1, c1 }; enum e2 { a2, b2, c2 = 0x80000000000 }; char *f(int); char *f(unsigned int); int main() { f(a1); //Which f? f(a2); //Which f? } 2. Standard Conversion void print(int); void print(char *); void set (int *); void set (const char *); int main() { print (0); //Which print? set (0); //Which set? } 3. Conversion Sequence int arr[3]; void putValues(const int *); int main() { putValues(arr); } 23OOP in C++Jan 2014
  • 24.
    new/delete operators  InC++, the new and delete operators provide built-in language support for dynamic memory allocation and de- allocation. int *pI = new int; int *pI = new int(102); //new initializes!! int *pArr = new int[4*num]; Arrays generally cannot be initialized. const int *pI = new const int(100); Array of constant cannot be created. delete pI; delete [] pArr;  new is polymorphic  new does more than malloc! 24OOP in C++Jan 2014
  • 25.
    new/delete & malloc/free All C++ implementations also permit use of malloc and free routines.  Do not free the space created by new.  Do not delete the space created by malloc  Results of the above two operations is memory corruption.  Matching operators  malloc-free  new-delete  new[] – delete []  It is a good idea to use only new and delete in a C++ program. 25OOP in C++Jan 2014
  • 26.
    CLASS Object Oriented Programmingin C++ Jan 2014 26OOP in C++
  • 27.
    TOPICS  Class Members Constructor & Destructor  Friends  Static Members  Struct & Union 27OOP in C++Jan 2014
  • 28.
    Class  C++ Classis an implementation of “type”  In C++, class is the only way to implement user defined data types.  A C++ class contains data members/attributes to specify the state and operations/methods to specify the behavior.  Thus, classes in C++ are responsible to offer needed data abstraction/encapsulation of Object Oriented Programming.  C++ Classes also provide means (through access specifier) to enforce data hiding that separates implementation from interface. 28OOP in C++Jan 2014
  • 29.
    Class  A Classis defined by “class” keyword.  Each member in a class has an access specifier.  private – these members are accessible inside the definition of the class.  public – these members are accessible everywhere.  Objects/instances of classes are to be created statically or dynamically.  Members can be accesses by “.” operator on the object.  The implicit this pointer holds the address of any object.  this pointer is implicitly passed to methods. 29OOP in C++Jan 2014
  • 30.
    A Simple Class classEmployee { public: void setName (const char *x) { name = strdup(x); } void setSalary (float y) { salary = y; } char *getName ( ) { return name; } float getSalary ( ) { return salary; } private: char *name; float salary; }; int main () { Employee e1; Employee *e2; e2 = new Employee; e1.setName(“Amit”); e2->name = strdup(“Ashis"); // Error e2.setSalary(29100); e2- >setSalary(29100); } Re-look at void setName (const char *x) { name = strdup(x); } Whose name? void setName (const char *x) { this->name = strdup(x); } Jan 2014 OOP in C++ 30
  • 31.
    More on this Type of this  X * const  Necessity of this to the programmer  Distinguishing data member from non-member variable  Explicit Use class DoublyLinkedNode DoublyLinkedNode::append(DoublyLinkedNode *x) { { DoublyLinkedNode *prev, *next; next = x; int data; x->prev = this; public: } void append(DoublyLinkedNode *x); } 31OOP in C++Jan 2014
  • 32.
    Constructor Functions  Constructorfunctions:  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 are created in the stack/static Store when their definition is encountered.  Objects can be created in the Free store with a pointer storing the address.  allow the class to initialise the state of an object 32OOP in C++Jan 2014
  • 33.
    Constructor Functions  Constructorfunctions:  Constructors also allocate additional memory space from the Free store (if) required for the object.  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.  If users do not define any constructor then the compiler provides a default constructor. 33OOP in C++Jan 2014
  • 34.
    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.  If there is at least one definition of constructor but no default constructor then the following statements are incorrect  X a;  X *pX = new X(); 34OOP in C++Jan 2014
  • 35.
    Destructor Functions  Destructorfunction:  is a member function named “~ <class-name>” (e.g. ~ String ( ) )  is automatically called when an object is destroyed, just before memory is freed  For auto variables when the variable goes out of scope  For objects created in the Free store, 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. 35OOP in C++Jan 2014
  • 36.
    Copy Constructor  Copyconstructor is a special constructor which is used to initialize an object with another object of the same type.  Copy constructor of class X takes an argument of type X &.  If the type of argument is X in stead of X&, an infinite loop results. 36OOP in C++Jan 2014
  • 37.
    Copy Constructor  Situationswhere 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. 37OOP in C++Jan 2014
  • 38.
    A Sample Class: String class String { public: String(); String(const String&); // Copy Constructor String(const char *); ~ String(); int length(); int read(); void print(); private: char *data; int len; } 38OOP in C++Jan 2014
  • 39.
    Class String::Constructor & Destructor String::String(){ data = NULL; len = 0; } String::String(const char *s) { data = new char[strlen(s)+1]; len = strlen(s); strcpy(data, s); } void ~String() { if (data != NULL) delete [] data; } int main() { String s1; //default constructor String s11(); //Error String s1(“test”); char str[6]; strcpy(str, “Hello”); String s2(str); String s3(s2); //Copy Constructor String s4 = new String(“one”); String s5 = new String(); delete s4; delete s5; } 39OOP in C++Jan 2014
  • 40.
    Arrays  Using Defaultconstructor while creating an array of objects  String arrayOfString[100]; // 100 objects created using the default constructor  Using specialized constructor while creating an array of objects.  String arrayOfString[2] = { String(“abc”), String(“def”) };  Using different constructor for creating array objects dynamically.  String *pArrayOfString[2] = { new String(“abc”), new String(“def”) }; 40OOP in C++Jan 2014
  • 41.
    Object Layout  Simplistically,an object of a class must have enough space to store all members of that class.  No space is required per object for storing function pointers for the methods declared in the class.  Methods on objects are translated by the compiler to C-like function calls by passing this pointer. A String Object data len H e l l o n 41OOP in C++Jan 2014
  • 42.
    Members as Objects Sometimes a class may have a data attribute which is an object of a class.  Employee class may have a member “name” whose type is String.  When an Employee object is initialized then name must also be initialized. 42OOP in C++Jan 2014
  • 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, 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 43OOP in C++Jan 2014
  • 44.
    Class Member: Notes It is always a good idea to define data members as “private”.  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.  May also lead to stunning consequences. 44OOP in C++Jan 2014
  • 45.
    Const Member Functions Constant Member Functions are not allowed to change the state of the object on which they are invoked.  Const Functions are declared with keyword const following member function parameter list.  const must also be present at the definition.  Type of this pointer passed to a const function is const X* const this class X { private: int ipriv; public: int ipub; int f() const; }; int X::f() const { int temp; temp = ipriv + ipub; //accessing members OK ipriv += temp; // cannot modify any member ipub -= temp; // cannot modify any member } 45OOP in C++Jan 2014
  • 46.
    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 46OOP in C++Jan 2014
  • 47.
    Friend Functions: Example classString { public : String(); String(const char *); String(int len); friend String concat(String *, String *) friend String concat(String *, char *); friend String concat(char *, String *); private : char *data; int len; } ; String::String(int len) { this->len = len; data = new char[len+1]; data[len] = ‘0’; } String concat(String *left, String *right) { String both[left->len + right->len + 1]; strcpy(both.data, left->data); strcat(both.data, right-> data) ; return both; } String concat(char *left, String *right) { String both[strlen(left) + right->len + 1]; strcpy(both.data, left); strcat(both.data, right->data); return both; } 47OOP in C++Jan 2014
  • 48.
    Friends of MoreThan One class class Matrix; // Forward declaration to make // declaration of crossprod legal class Vector { public : Vector(int n) ; friend Vector prod(Matrix *pM, Vector *pV); private : int elements[10] ; int n; }; class Matrix { public : Matrix(int m, int n) ; friend Vector prod(Matrix *pM, Vector *pV); private : int elements[10][10]; int m, n; }; Vector prod(Matrix *pM, Vector *pV) { int V(pM->m); for (i = 0; i < pM->m; i++) for (j = 0; j < pM->n; j++) { v[i] += pm->elements[i][j]* pV->elements[i]; } } 48OOP in C++Jan 2014
  • 49.
    Friend Members &Class  Member of a different class may be a friend function.  A class may be declared as a friend implying all member functions of that class are friends.  Friend-ship is neither commutative nor transitive.  Friends tend to break data hiding.  It is best to avoid friend in an ideal OO Design. class Matrix; class Vector { public: void Vector(int n); Vector prod(Matrix *pM); int elements[10]; int n; } ; class Matrix { public: void Matrix(int m, int n); friend Vector Vector::prod(Matrix *pM); private: int elements[10][10]; int m, n; } ; 49OOP in C++Jan 2014
  • 50.
    Static Data  Astatic data member is shared by all the objects of a class.  Static data member may be public or private.  Static data member must be initialized in a source file.  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; // This is a declaration X() { count++; } } X::count = 0; //Definition & Initialization int main() { X a, b, c; printf(“%d %d %d %dn”, X::count, a.count, b.count, c.count); } The output will be 3 3 3 3 50OOP in C++Jan 2014
  • 51.
    Static Data: AList class ListNode { public: static ListNode *first; private: ListNode *next; int data; public: ListNode(int x); print(); } List Node *ListNode::first = NULL; ListNode::ListNode(int x) { data = x; next = NULL; if (first == NULL) first = this; else { next = first; first = this; } } void ListNode::print() { ListNode *x; x = ListNode::first; while (x != NULL) { printf(“%d “, x->data); x = x->next; } printf(“n”); } int main() { ListNode x(5); ListNode x(7); ListNode x(8); x.print(); } The output will be 8 7 5 51OOP in C++Jan 2014
  • 52.
    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.static_function (args);  this pointer is not passed to a static function  must not refer to non-static members of its “invoking object”  Philosophy of static members. 52OOP in C++Jan 2014
  • 53.
    Static Members inInline Functions  Not Safe X.hxx Class X { public: static void f(); static String g(); private: static String s; } inline String X::g() { // do some operation on s return s; } X.cxx #include “X.hxx” void X::f() { X::g(); } The above code will not fail; The code in the following may fail however. X1.cxx #include “X.hxx” int main() { X::g(); } Data members are guaranteed to be initialized before any non- inline function is called. 53OOP in C++Jan 2014
  • 54.
    OPERATOR OVERLOADING Object OrientedProgramming in C++ Jan 2014 54OOP in C++
  • 55.
    Overloading Operators  Semanticsof an operator is represented by a function named operator op, where op is an operator symbol (+,*, - , [ ], etc. )  These functions can either be implemented as global friend functions and/or methods. 55OOP in C++Jan 2014
  • 56.
    Overloading Operators  Example Let ‘+’ denote concatenation for Strings.  “s1 + s2” denote concatenation of strings s1 and s2.  An expression of the form “s1+s2” is converted to s1.operator+(s2) if there is a function named “operator+” defined in the class String.  “s1+s2” is also equivalent to operator+(s1, s2) if a global function named “operator+” is properly defined; typically such global functions are friends to the class String. 56OOP in C++Jan 2014
  • 57.
    Example of overloading operator+ / * string .h * / const int max_string_length = 128 ; class String { public : String operator + (char *text) ; String operator + (String &s1) ; String (char *data); String () { data = NULL; len = 0; } private : char *data; int len; } ; String operator+(char * text) { char *save = new char[len+1]; strcpy(save, data); data = new char[len +strlen(text) + 1]; strcpy(data, save); stcat(data, text); delete[]save; return (*this); } 57OOP in C++Jan 2014
  • 58.
    Overloading Assignment Operator String &String: :operator=( char *rhs) { data = new char [strlen(rhs) + 1]; strcpy ( data, rhs); return *this ; } Bug:  Memory Leak as previous data of this is not deleted. . . . String String: :operator=( String &rhs) { data = new char [rhs.len + 1]; strcpy ( data, rhs.data); return *this ; } 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 & 58OOP in C++Jan 2014
  • 59.
    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) . 59OOP in C++Jan 2014
  • 60.
    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; } Problem: Returning reference to a local object. The code fails. Integer & operator*(Integer &lhs, Integer &rhs) { Integer *result = new Integer( lhs.data * rhd.data); return *result; } Who deletes? The caller. What about the following use? Integer a(1), b(2), c(3), d(3); Integer e = a*b*c*d; 60OOP in C++Jan 2014
  • 61.
    More On “=”Operator Overloading  There is a system defined implementation of assignment operator. In absence of user defined assignment operator function, systems’ function is used.  System defined function makes a shallow copy.  Some times shallow copying may be dangerous  If the constructor uses new, assignment operator may have to be overloaded.  If there is a need to define a copy constructor then there must be a need to overload assignment operator and vice-versa. 61OOP in C++Jan 2014
  • 62.
    Overloading Unary Operators Typically methods implementing unary operators will not have any argument.  Exceptions:  post increment and post decrement operators.  As there are two operators with the same symbol “+ +”, the name of the function is the the same.  Prototype for pre increment function:  void operator ++ ( );  Prototype for post increment function:  void operator ++ (int a); 62OOP in C++Jan 2014
  • 63.
    Operator Overloading Facts Some operators can not be implemented as global(friend) functions.  =, [] etc.  Some Operators cannot be overloaded  ::,.*.?:,., sizeof() etc.  Precedence or arity of an operator cannot be changed by overloading an operator.  Conditional Operators like &&, ||, comma operator should not be overloaded. 63OOP in C++Jan 2014
  • 64.
    Friends Vs Methods Members are better in terms of restriction of scope which results in efficient searching for best function to resolve overloading.  Members will not help if the left hand side of the operator is not of the class type.  String s1 = “abc” + s2; // may be wrong  In case of overloading stream operators, we need friend due to the reason stated above.  Resolving in case of a conflict between friend and method. 64OOP in C++Jan 2014
  • 65.
    Returning const froma function  Consider the following definition const Rational & operator * (const Rational & lhs, const Rational & rhs);  If the function returns a non-const, the following is valid. Rational a, b, c; (a * b) = c;  Retuning const ensures that overloaded “*” is compatible with the same operator on built-in types. Jan 2014 OOP in C++ 65
  • 66.
    Overloading using const ClassString { public: char & operator [ ] (int pos) { return data[pos]; } const char & operator [ ] (int pos) { return data[pos]; } private: char * data; …… } String s1 = “Hello”; cout << s[0]; // fine s[0] = ‘x’; // fine const String cs = “World”; cout << s[0]; // fine s[0] = ‘x’; // Error!!! Jan 2014 OOP in C++ 66
  • 67.
    Bit-wise const vs.Conceptual const  What should a constant member function preserve?  Bit-wise const-ness  Conceptual const-ness  Bit-wise const member functions may become unsafe.  Conceptual const member function may need to change some bits of the object  mutable keyword. Jan 2014 OOP in C++ 67
  • 68.
  • 69.
    Topics  Fundamentals of Inheritance  protected Access Specifier Initialization  Virtual Functions  Jan 2014 69OOP in C++
  • 70.
    Reusability  Reuse analready 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 2014 70OOP in C++
  • 71.
    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.  All (?) data members and methods of the base class are immediately available to the derived class.  Thus, 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 2014 71OOP in C++
  • 72.
    Accessibility of BaseClass 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, 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, private members of the base class are not directly accessible to the members in the derived class. Jan 2014 72OOP in C++
  • 73.
    Assume the following classhierarchy class C: public B { .. }; class B: public A { .. }; class A { .. }; Object Layout in Inheritance Layout for an object of type C A-Part Data Member B-Part Data Member C-Part Data Member Jan 2014 73OOP in C++
  • 74.
    protected Members  privatedata members of the base class cannot be directly accessed by the methods of the derived class.  However, 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. Jan 2014 74OOP in C++
  • 75.
    Syntax of Inheritance An example class Employee { protected: float basic; long id; public: Employee(long id); float getSalary(); }; class Manager : public Employee { protected: Employee *supervised[10]; int numberOfPeopleManaged; public: Manager(Id, n); float getSalary(); void printSupervisedEmployeeId(); } Jan 2014 75OOP in C++
  • 76.
    Order of ConstructorCalls  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 derived class calls an appropriate constructor of the base class  Therefore, the constructor of the base class is executed first and then the constructor of the derived class is executed. Jan 2014 76OOP in C++
  • 77.
    Example of DerivedClass Constructor Employee::Employee(long id) { this->id = id; } Manager::Manager(long id, int n) : Employee(id) { numberOfPeopleManaged = n; } Jan 2014 77OOP in C++
  • 78.
    Order of DestructorCalls  The destructor of the derived class is responsible for cleaning up the state of the derived object.  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, the destructor of the base class is executed first and then the destructor of the derived class is executed. Jan 2014 78OOP in C++
  • 79.
    Casting  Derived classpointer can be implicitly cast to a base class pointer Manager m; Employee *e = &m; // Employee *e = (Employee *)(&m);  Only base class part of the derived object can be seen through the base pointer. e-> printSupervisedEmployeeId(); //error Jan 2014 79OOP in C++
  • 80.
    Casting  A Baseclass pointer cannot be implicitly cast to a derived class pointer Manager *pM; pM = e; //error pM = (Manager *)e; //ok Down casting may be dangerous Jan 2014 80OOP in C++
  • 81.
    Static vs. DynamicBinding  Binding refers to associate a type to a name.  Consider the following example: Manager m; Employee *e = &m; e->getSalary(); //Which getSalary? Employee or Manager?  “e” is declared as a pointer to Employee Jan 2014 81OOP in C++
  • 82.
    Static vs. DynamicBinding  Continue on the example: Manager m; Employee *e = &m; e->getSalary(); //Which getSalary? Employee or Manager?  In the example however, it makes more sense to mean “getSalary” of the Manager class.  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 2014 82OOP in C++
  • 83.
    Virtual Functions  InC++, dynamic binding is made possible only for pointer & reference data types and for methods that are declared as virtual in the base class.  If a method is declared as virtual, it can be overridden in the derived class.  If a method is not virtual and it is re- defined in the derived class then the latter definition hides the former one. Jan 2014 83OOP in C++
  • 84.
    Virtual Function: Example classX{ class Y: public X{ public: public: int f(){ return 2; } int f(){ return 4;} virtual int g(){ return 3;} int g(){ return 6;} }; }; main() { Y a; int i, j , k, m; X *b = &a; i = b->f(); j = a.f(); k = b->g(); m = a.g(); printf(“%d %d %d %dn”, i, j, k, m); } Jan 2014 84OOP in C++ Output will be 2 4 6 6
  • 85.
    Redefining a Non-Virtual Function Simply do not do that. class X() { class Y : public X { protected: protected: void f(); void f(); }; }; int main() { Y y1; Y *pY; X *pX; pX = &y1; pX->f(); // f as defined in X will be called pY = &y1; pY->f(); // f as defined in Y will be called } Jan 2014 85OOP in C++
  • 86.
    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.  During object creation, the actual address of the function is assigned to the function pointer.  Y is derived from X, which has a virtual function. X-part-data X-part-virtual-function-ptr Y-part-data Actual definition of the virtual function Jan 2014 86OOP in C++
  • 87.
    Abstract Class  PureVirtual Function  A virtual function may be assigned to NULL meaning that this function is declared but not defined in a class.  Definition of such a class is incomplete.  A class with one or more pure virtual function is called an abstract class.  Abstract class cannot be instantiated.  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. Jan 2014 87OOP in C++
  • 88.
    Virtual Destructor  Constructorscannot be virtual  For a base class which has been derived from, the destructor must be declared virtual.  Occasionally we create a derived object and store it using a pointer to Base class such as  Base *pBase = new Derived(/*arguments*/);  If we destroy this object using “delete pBase” then two destructors need to be called.  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 2014 88OOP in C++
  • 89.
    Inheritance Example: Polymorphic Array Consider an abstract base class Shape which contains a pure virtual function “CalculateArea”.  Suppose three classes Triangle, Rectangle and Circle derived from Shape.  Consider a main function that creates different Shape objects and store them in an array.  If in a for loop the function calculateArea is called on all objects in the array, we see dynamic binding in use. Jan 2014 89OOP in C++
  • 90.
    Polymorphic Array: Class Definitions classShape { public: virtual double calculateArea() = 0; }; class triangle : public Shape() { private: Point a, b, c; Triangle(double x_a, double y_a, double x_b, double y_b, double x_c, double y_c); public: double calculateArea(); }; class Circle : public Shape() { private: Point centre; double radius; Circle(double x_centre, double y_centre, double r);, public: double calculateArea(); }; Jan 2014 90OOP in C++
  • 91.
    Polymorphic Array: main function intmain() { Shape *pArr = NULL; int n = getInput(pArr); for (int i = 0; i < n; i++) { double area = Shape[i]->calculateArea(); printf (“%d %lf n”, i, area); } } int getInput(Shape *pArr) { printf(“Which Shape do you want to create?n”); printf(“Write 1 for triangle, 2 for rectangle, 3 for circle and 0 to quitn”); int i, double x_a, x_b, x_c, y_a, y_b, y_c; while (1) { int j = 0; scanf(“%d”, &i); switch (i) { case 0: break; case 1: scanf(“%f%f%f%f%f%f”, &x_a, &y_a, &x_b, &y_b, &x_c, &y_c); pArr[j++] = new Triangle(&x_a, &y_a, &x_b, &y_b, &x_c, &y_c); break; …….. } } } Jan 2014 91OOP in C++
  • 92.
    Inheritance: Benefits  CodeSharing/Reuse  Consistency of Interface  Construction of Software Components  Rapid Prototyping  Information Hiding Jan 2014 92OOP in C++
  • 93.
    Inheritance: Cost  ExecutionSpeed  Program Size  Message Passing Overhead  Program Complexity Jan 2014 93OOP in C++
  • 94.
    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 2014 94OOP in C++
  • 95.
    Inheritance Notes  Constructorscannot be virtual  Calling a virtual function from within a constructor does not have the desired effect.  The following code is buggy. Tell why. void f(Base *b) { int main() { b[0].f(); b[1].f(); Derived d[10]; } f(d); }  Derived is publicly derived from Base.  Class Base has a virtual function “f” which is redefined in Derived. Jan 2014 95OOP in C++
  • 96.
    Default Parameter &Virtual Function  Do not change the default parameter in a redefined virtual function class X() { class Y : public X { protected: protected: virtual void f(int i = 10); virtual void f(int i =20); }; }; int main() { Y y1; Y *pY; X *pX; pX = &y1; pX->f(); // f with value of i as 10 will be called pY = &y1; pY->f(); // f with value of i as 20 will be called } Jan 2014 96OOP in C++
  • 97.
    Is an Ostricha Bird  Suppose there is a base class Bird  a virtual method fly returns altitude > 0.  A class Ostrich is derived from Bird.  fly method has to be redefined as an empty function.  Leads to a logical dilemma.  Can an overridden method be empty?  Can an overridden method throw exceptions? Jan 2014 97OOP in C++
  • 98.
    Is a Circlean Ellipse?  Circle is a special type of ellipse.  Let Circle be derived from Ellipse.  Suppose that Ellipse has a method setSize(x,y).  Also suppose that there is a function sample as defined below. sample (Ellipse &e) { e. setSize(10,20); ……. }  If sample is called on a circle, strange things happen!  Subset is not substitutable!! Jan 2014 98OOP in C++
  • 99.
    Should a Stackinherit from a List?  Probably Not!  If List is the base class of Stack  Methods such as push, pop etc. 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.  A Stack has a List. Jan 2014 99OOP in C++
  • 100.
    Multi-level Inheritance  Supposethat C is derived from B and B is derived from A.  Suppose that a method, f, in A is virtual.  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.  It is advisable to explicitly write “virtual” in front of the definition of f in B as, otherwise, an implementer of C may think that f is not a virtual method. Jan 2014 100OOP in C++
  • 101.
    Inheritance & CodeReuse  Suppose that C and B and are derived from A.  Both C and B contain a function f ; therefore, f is made a virtual (not pure) function in A.  This is bad.  A new class D is required to be derived from A later.  f in D is different than A.  Interfaces should not have implementation. Jan 2014 101OOP in C++
  • 102.
    private Inheritance  IfB 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 2014 102OOP in C++
  • 103.
    protected Inheritance  IfB 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 2014 103OOP in C++
  • 104.
    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 2014 104OOP in C++
  • 105.
    TYPE CASTING Object-Oriented Programmingin C++ Jan 2014 OOP in C++ 105
  • 106.
    Type Casting  Whycasting?  Casts are used to convert the type of an object, expression, function argument, or return value to that of another type.  (Silent) Implicit conversions.  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 2014 OOP in C++ 106
  • 107.
    Type Casting To performa type cast, the compiler  allocates temporary storage  Initializes temporary with value being cast float f (int i,int j) { return (float ) i / j; } // compiler generates: float f (int i, int j) { float temp_I = i, temp_j = j; return temp_i / temp_j; } 107OOP in C++Jan 2014
  • 108.
    Automatic (Implicit) Conversion Automatic conversions from one type to other may be extremely convenient.  Automatic conversions (either conversion operators or single argument non-explicit constructors) are unsafe as well.  can interfere with overload resolutions.  can silently let wrong code compile cleanly. String s1, s2, s3; s3 = s2 – s1; // Though “-” is not overloaded in String Jan 2014 OOP in C++ 108
  • 109.
    Casting to UserDefined 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; s1 = “example”; 109OOP in C++Jan 2014
  • 110.
    Casting to UserDefined 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”; 110OOP in C++Jan 2014
  • 111.
    Ambiguities: Example  Overuseof 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; } 111OOP in C++Jan 2014
  • 112.
    Ambiguity: Example class B; classA { 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 112OOP in C++Jan 2014
  • 113.
    Casting from ClassTypes  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 *()” . 113OOP in C++Jan 2014
  • 114.
    Example of userdefined cast const int max_string_length = 128; class String { public: String ( ) : String (const String & ) ; String (const char *); ~String ( ) ; String & operator = (const String & ) ; operator const char * ( ) const ; int length ( ) const ; int read ( ) ; void print ( ) const ; . . private: char text [max_string_length+1] }; void operator-(const String &, const String &); int main ( ) { int fd; String filename = “tmp/test”; // cast filename to type const char * fd = open (filename, O_WRONLY | O_CREAT, 0666); write (fd, “test”, 4); close (fd); // not legal, since we can cast only to const char * // strcpy (filename, “zbc”); String name = “Zaphod Beeblebrox”; name – “Beeblebrox”; // is now ambiguous. return 0 ; } 114OOP in C++Jan 2014
  • 115.
    Avoiding Ambiguities const intmax_string_length = 128; class String { public: String ( ) ; String (const String & ) ; String (const char *); ~ String ( ) ; String & operator = (const String & ); const char *as_char_pointer ( ) const; int length ( ) const; int read ( ); void print ( ) const; ... private: char text [max_string_length+1]; }; void operator-(const String &, const String &); int main ( ) { int fd; String filename = “/tmp/test”; // convert filename to type char * fd = open (filename.as_char_pointer ( ), O_WRONLY | O_CREAT, 0666); write (fd, “test”, 4); close (fd); // not legal // strcpy (filename.as_char_pointer ( ), “zbc”); String name = “Zaphod Beeblebrox”; name – “Beeblebrox”; // is no longer ambiguous return 0; } 115OOP in C++Jan 2014
  • 116.
    Casting Pointers &References  Casting a value:  float f_var = 3.14;  cout << (int) f_var;  creates a temporary object  does not violate data encapsulation  Casting a pointer or reference  cout << *(( int *) &f_var);  cout << (int &) f_var;  Re-interprets representation of object  Violates data encapsulation 116OOP in C++Jan 2014
  • 117.
    C++ casts  Thereare four cast operators in C++  const_cast  static_cast  reinterpret_cast  dynamic_cast  Only dynamic_cast is not equivalent to a C-style cast 117OOP in C++Jan 2014
  • 118.
    Prefer C++ caststo 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.  More narrowly specified purpose for each specified cast; compilers can diagnose user errors.  Some casts are performed safely at run-time. Jan 2014 OOP in C++ 118
  • 119.
    const_cast operator  Syntax: const_cast < type-id > ( expression )  The const_cast operator can be used to remove the const, 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, volatile qualifiers. Applying on pointers and references, the result will refer to the original object.  The const_cast operator cannot be used to directly override a constant variable's constant status. Jan 2014 OOP in C++ 119
  • 120.
    const_cast operator: Example Example #include<iostream> class CCTest { public: void setNumber( int ); void printNumber() const; private: int number; }; void CCTest::setNumber( int num ) { number = num; } void CCTest::printNumber() const { cout << "nBefore: " << number; const_cast< CCTest * >( this )- >number--; cout << "nAfter: " << number; } int main() { CCTest X; X.setNumber( 8 ); X.printNumber(); }  On the line containing the const_cast, the data type of the this pointer is const CCTest *. The const_cast operator changes the data type of the this pointer to CCTest *, allowing the member “number” to be modified. The cast lasts only for the remainder of the line on which it appears. Jan 2014 120OOP 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.  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 2014 121OOP in C++
  • 122.
    Guidelines for const const is a powerful tool for writing safer code; use it as much as possible but no more.  Do not use const pass-by-value parameters in function declarations. This is not useful and misleading at best.  When returning a user defined type, prefer returning a const value.  Do not return handles to internal data from a const member function. Jan 2014 OOP in C++ 122
  • 123.
    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, meaning and restrictions as C-style cast. It cannot be used to convert a struct into an int or a double into a pointer. Jan 2014 OOP in C++ 123
  • 124.
    static_cast operator  Ingeneral, a complete type can be converted to another type so long as some conversion sequence is provided by the language.  may also use static_cast to convert any expression to a void, in which case the value of the expression is discarded.  It cannot change the const-ness of an expression. Jan 2014 OOP in C++ 124
  • 125.
    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 ... }. static_cast: Example  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 run- time type check is made to ensure the safety of the conversion.For such conversions dynamic_cast should be used. Jan 2014 125OOP in C++
  • 126.
    C-style casts VSstatic-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 2014 OOP in C++ 126
  • 127.
    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 2014 127OOP in C++
  • 128.
    reinterpret_cast operator  Theresult of a reinterpret_cast cannot safely be used for anything other than being cast back to its original type. Other uses are, at best, non-portable.  The reinterpret_cast operator cannot cast away the const, volatile attributes.  One practical use of reinterpret_cast is in a hash function, which maps a value to an index in such a way that two distinct values rarely end up with the same index.  Reinterpret_cast should rarely be used in a C++ program Jan 2014 OOP in C++ 128
  • 129.
    reinterpret_cast: Example Example #include <iostream> unsignedshort Hash( void *p ){ // Returns a hash code based on an address unsigned int val = reinterpret_cast<unsigned int>( p ); return ( unsigned short )( val ^ (val >> 16)); } int main(){ int a[20]; for ( int i = 0; i < 20; i++ ) cout << Hash( a + i ) << endl; }  The reinterpret_cast allows the pointer to be treated as an integral type. The result is then bit-shifted and XORed with itself to produce a unique index (unique to a high degree of probability). The index is then truncated by a standard C-style cast to the return type of the function. Jan 2014 129OOP in C++
  • 130.
    Usage of casts classA { public: virtual ~A(); …}; class B : private virtual A { …}; class C : public A { … }; class D : public B, public C { …}; A a1; B b1; C c1; D d1; const A a2; const A& ra1 = a1; const A& ra2 = a2; char c;  A *pa = (A *)&ra1;  Use const_cast  B * pb = (B*)&c1;  Use reinterpret_cast  A *pa = (A*)&a2;  Cannot be expressed in a new-style cast.  void *pv = &b1;  B *pb = (B*)(pv);  Use static_cast instead; Jan 2014 OOP in C++ 130
  • 131.
    Avoid Unnecessary Cast Look at the cast and comment class SpecialWindow: public Window { // derived class public: virtual void onResize() { // derived onResize impl; static_cast<Window>(*this).onResize(); // cast *this to Window, // then call its onResize; // this doesn’t work! ... // do SpecialWindow- } // specific stuff ... }; Jan 2014 OOP in C++ 131
  • 132.
    type_info class  Thetype_info class describes type information generated within the program by the compiler. The entire definition of this class is implementation dependent but the following features of this class is standardized.  Objects of this class effectively store a pointer to a name for the type. The type_info class also stores an encoded value suitable for comparing two types for equality or collating order.  The operators “==“ and “!=“ are overloaded and can be used to compare for equality and inequality with other type_info objects, respectively. Jan 2014 OOP in C++ 132
  • 133.
    type_info class  Featuresof type_info class (contd):  The “name” member function returns a const char* to a null-terminated string representing the human- readable name of the type. The memory pointed to is cached and should never be directly deallocated.  Type information is generated for polymorphic classes only if the /GR (Enable Run-Time Type Information) compiler option is specified. Jan 2014 OOP in C++ 133
  • 134.
    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 result of typeid is a const type_info&.  The typeid operator does a run-time check when applied to an l-value of a polymorphic class type, where the true type of the object cannot be determined by the static information provided. Such cases are: a reference/ Pointer 134OOP in C++Jan 2014
  • 135.
    typeid operator  Whenthe operand of typeid is of a non- polymorphic class type, the result is the type of the operand not the type of the underlying object.  type-id may be used with operands of built-in types. 135OOP in C++Jan 2014
  • 136.
     The expressionusually points to a polymorphic type (a class with virtual functions).  The pointer must be de- referenced so that the object it points to is used. Without de-referencing the pointer, the result will be the type_info for the pointer, not pointee Example #include <iostream> #include <typeinfo.h> class Base { public: virtual void vvfunc() {} } class Derived : public Base {}; typeid:Example int main(){ Derived* pd = new Derived; Base* pb = pd; cout << typeid( pb ).name() << endl; //prints "class Base *” cout << typeid( *pb ).name() << endl; //prints "class Derived" cout << typeid( pd ).name() << endl; //prints "class Derived *" cout << typeid( *pd ).name() << endl; //prints "class Derived" delete pd; } 136OOP in C++Jan 2014
  • 137.
    dynamic_cast operator  Syntax: dynamic_cast<type- id> (expression)  The expression dynamic_cast<type- id>( expression) converts the operand expression to an object of type type- id.  It is used for down- casting. Example class B { ... }; class C : public B { ... }; class D : public C { ... }; void f(D* pd){ C* pc = dynamic_cast<C*>(pd); // ok: C is a direct base class, pc points to C subobject of pd B* pb = dynamic_cast<B*>(pd); // ok: B is an indirect base class , pb points to B subobject of pd ... } 137OOP in C++Jan 2014
  • 138.
    dynamic_cast: Example Example: class B{ ... }; class D : public B { ... }; void f(){ B* pb = new D; // unclear but ok B* pb2 = new B; D* pd = dynamic_cast<D*>(pb); // ok: pb actually points to a D ... D* pd2 = dynamic_cast<D*>(pb2); // pb2 points to a B not a D the cast is bad so pd2 is NULL ... } 138OOP in C++Jan 2014
  • 139.
    dynamic_cast  If dynamic_castto a pointer type fails, the result of the dynamic_cast is null; if dynamic_cast to a reference type fails, an exception is thrown.  dynamic_cast is performed at run-time.  dynamic_cast can be used only for pointer or reference types to navigate a class hierarchy. The dynamic_cast operator can be used to cast from a derived class pointer to a base class pointer, cast a derived class pointer to another derived (sibling) class pointer, or cast a base class pointer to a derived class pointer. Each of these conversions may also be applied to references. 139OOP in C++Jan 2014
  • 140.
    dynamic_cast  dynamic_cast operatorcannot be used for built-in types.  All of the derived-to-base conversions are performed using the static (compile-time) type information. These conversions may, therefore, be performed on both non- polymorphic and polymorphic types. These conversions will produce the same result if they are converted using a static_cast. However, even these results may be wrong in the presence of multiple inheritance.  dynamic_cast is strongly recommended to be applied on polymorphic types. 140OOP in C++Jan 2014
  • 141.
    Cost of dynamic_cast The pointer to the type_info object of a class is stored in the vtbl array of the class.  Thus, 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.  Size of the objects do not increase for RTTI operations.  Cost of RTTI at run time is similar to the cost of calling a virtual function; cost of calling a virtual function is the same as the cost of calling a function through a function pointer. 141OOP in C++Jan 2014
  • 142.
    EXCEPTIONS Object Oriented Programmingin C++ Jan 2014 142OOP in C++
  • 143.
    Topics  Basic Conceptof Exceptions  try-catch block in C++  Semantics of throw Jan 2014 143OOP in C++
  • 144.
    Error Handling inC++  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. Jan 2014 144OOP in C++
  • 145.
    Error Handling inC++  Error Condition Handling - C++ Style  On error condition an exception object is created and thrown.  A function catches exception objects generated from the function it calls in a distinct control flow.  Similar Exception objects can enjoy benefits of inheritance. Jan 2014 145OOP in C++
  • 146.
    C-Style Error Handling int Calculator::divide(int i) { if (i == 0) { // what do we do? } else { value /= i; } return value; }  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 2014 146OOP 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.  “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 2014 147OOP in C++
  • 148.
    Exception Object andthrow  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, a suitable Exception object is thrown. Semantics of throw is as follows.  Creation of an object (function of new)  passing control from this function to the caller function (similar to return)  Unlike return, throw initiates unwinding of the call stack till the exception is handled. Jan 2014 148OOP in C++
  • 149.
    Example of ExceptionHandling in C++ class DivideByZero { private: int dividend; public: print() { cout << dividend << “is divided by zero” <<endl; } DivideByZero(int d) { dividend = d; } }; int Calculator::divide(int i) throws DivideByZero { if (i ==0) throw DivideByZero(value); value /= i; return value; } int main (int argc, char **argv) { int i = 0; Calculator c; try { c.divide (0); cout << c.getValue (); } catch (DivideByZero& ext) { ex.print(); return 1; } return 0; } Jan 2014 149OOP 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.  Control passes to first matching catch block  Can handle the exception and continue  Can free resources and re-throw Jan 2014 150OOP in C++
  • 151.
    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.  catch blocks after a try block are examined in order when an exception is thrown from a function called in the try block.  Parentheses for each catch block has semantics of a “function argument declaration” Jan 2014 151OOP in C++
  • 152.
    Exception Specifications // canthrow anything void Calculator::subtract (int i); // promises not to throw void Calculator::add (int i) throw (); // promises to only throw int void Calculator::divide (int i) throw (int);  Make promises to the caller  Allow stronger type checking enforced by the compiler  By default, 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  A throw clause with no types  Promises nothing will be thrown  Can list multiple types  Comma separated Jan 2014 152OOP in C++
  • 153.
    Stack Frame  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 run- time. Contains:  The frame pointer  The return address for the call (i.e., where it was called from)  Parameters passed to the function  Automatic (stack) variables for the function previous frame pointer return address parameters automatic variables Jan 2014 153OOP in C++
  • 154.
    Illustrating the CallStack int main (int argc, char **argv) { int i = 0; Calculator c; try { c.divide (0); cout << c.get_value (); } catch (int) { return 1; } return 0; }  Stack frame for function main  Pushed on program call stack  With stack variables i and c  With parameters argc and argv  Note that parameters are initialized at frame creation  Variables are not necessarily initialized at frame creation  May occur later in called function argc argv i c value_ main Jan 2014 154OOP in C++
  • 155.
    Illustrating the CallStack, cont. int main (int argc, char **argv) { int i = 0; Calculator c; try { c.divide (0); cout << c.get_value (); } catch (int) { return 1; } return 0; }  Enter function main  Stack variable initialized to 0 argc argv i c value_ main Jan 2014 155OOP in C++
  • 156.
    Illustrating the CallStack, cont. int main (int argc, char **argv) { int i = 0; Calculator c; try { c.divide (0); cout << c.get_value (); } catch (int) { return 1; } return 0; }  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 argc argv i c value_ main Calculator:: Calculator( ) this Jan 2014 156OOP in C++
  • 157.
    Illustrating the CallStack, cont. Calculator::Calculator () : value_ (0) {} void Calculator::divide (int i) throw (int) { if (i == 0) { throw i; } else { value_ /= i; } cout << value_; }  Enter function Calculator::Calculator ( )  Member variable value_ of stack variable c is initialized to zero  How do we know which value_ to set?  There may be multiple Calculator instances  Answer: implicit “this” parameter in stack frame argc argv i c value_ main Calculator:: Calculator() this Jan 2014 157OOP in C++
  • 158.
    Illustrating the CallStack, cont. Calculator::Calculator () : value_ (0) { } void Calculator::divide (int i) throw (int) { if (i == 0) { throw i; } else { value_ /= i; } cout << value_; }  Return from function Calculator::Calculator ( )  Pop the stack frame, return to previous argc argv i c value_main Jan 2014 158OOP in C++
  • 159.
    Illustrating the CallStack, cont. int main (int argc, char **argv) { int i = 0; Calculator c; try { c.divide (0); cout << c.get_value (); } catch (int) { return 1; } return 0; }  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 void Calculator:: divide (int ) main argc argv i c value_ this i Jan 2014 159OOP in C++
  • 160.
    Illustrating the CallStack, cont.  Enter function Calculator::divide (int)  Test i equal to 0 and take the true branch  Throw integer i main void Calculator:: Calculator (int ) argc argv i c value_ this i Calculator::Calculator () : value_ (0) { } void Calculator::divide (int i) throw (int) { if (i == 0) { throw i; } else { value_ /= i; } cout << value_; } Jan 2014 160OOP in C++
  • 161.
    Illustrating the CallStack, cont. Calculator::Calculator () : value_ (0) { } void Calculator::divide (int i) throw (int) { if (i == 0) { throw i; } else { value_ /= i; } cout << value_; }  Thrown exception unwinds call stack  Notice control skips over cout statement to end  Pop the stack frame, return to previous  Return from function void Calculator::divide ( ) argc argv i c value_ main Jan 2014 161OOP in C++
  • 162.
    Illustrating the CallStack, cont. int main (int argc, char **argv) { int i = 0; Calculator c; try { c.divide (0); cout << c.get_value (); } catch (int) { return 1; } return 0; }  We’ve reached an enclosing try/catch scope  So stack unwinding stops  Control jumps to first matching catch block  Again, skips over intervening cout statement argc argv i c value_ main Jan 2014 162OOP in C++
  • 163.
    More on catch try{ // can throw an exception } catch (Derived &d) { // ... } catch (Base &b) { // ... } catch (...) // catch all... { // ... }  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 Jan 2014 163OOP in C++
  • 164.
    A Few Moreon catch try { // can throw an exception } catch (MyClass &e) { // ... throw; // rethrows e } catch (int) { // ... } catch (...) // catch all... { // ... }  Notice catch-by-reference for user defined types  More efficient  Only a reference propagates  Rather than entire object  More correct  Avoids class-slicing problem if catch as base type, rethrow  Preserves polymorphism  More on this in later lectures  Can leave off variable name  Unless catch block needs to do something with the instance that was caught Jan 2014 164OOP in C++
  • 165.
    TEMPLATES Object-Oriented Programming inC++ Jan 2014 OOP in C++ 165
  • 166.
    What is aTemplate?  Templates are specifications of a collection of functions or classes which are parameterized by types.  Examples:  Function search, min etc..  The basic algorithms in these functions are the same independent of types.  But, we need to write different versions of these functions for strong type checking in C++.  Classes list, queue etc.  The data members and the methods are almost the same for list of numbers, list of objects.  We need to define different classes, however. Jan 2014 166OOP in C++
  • 167.
    template<class X> voidswap (X &one, X &other) { X temp; temp = one; one = other; other = temp; } Main() { int I=10, j=20; swap(I, j); String s1(“abc”), s2(“def”); swap(s1, s2); } Function Template: An Example void swap(int &i, int &j) { int temp; temp = i; i = j; j = temp; } void swap(String &i, String &j) { String temp; temp = i; i = j; j = temp; } Type parameter Type parameter list Template instantiation Jan 2014 167OOP in C++
  • 168.
    Parameterized Functions  Afunction template  describes how a function should be built  supplies the definition of the function using some arbitrary types, (as place holders),  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 class, (i.e. type), parameters Jan 2014 168OOP in C++
  • 169.
    Template Non-type Parameter It is an ordinary parameter  template <class T, int size> T min (T (&x[size]));  When min is called, size is replaced with a constant value known at compile time  The actual value for a non-type parameter must be a constant expression. Jan 2014 169OOP in C++
  • 170.
    typename  The keywords 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 2014 170OOP in C++
  • 171.
    Template Argument Deduction Each item in the template parameter list is a template argument  When a template function is invoked, the values of the template arguments are determined by seeing the types of the function arguments template <class T, int size> Type min( T(&x[size])); int pval[9]; min(pval); //Error!! Jan 2014 171OOP in C++
  • 172.
    Template Argument Deduction Three kinds of conversions are allowed.  L-value transformation (e.g., 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 2014 172OOP in C++
  • 173.
    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, T y);  unsigned int ui; min (ui, 1024); //Error!!  min<unsigned int>(ui, 1024); // OK  Specifying return type generically is often a problem.  template <class T, class U> ??? sum(T x, U y);  sum(ch, ui) returns U; sum (ui, ch) returns T  template < class R, class T, class U> R sum(T x, U y)  min<int>(i, ‘a’); Jan 2014 173OOP in C++
  • 174.
    Template Explicit Specialization Some times, a template may not be suitable for all types.  The following template is not good for char * template <class T> T min(T x, T y) { return (x < y) ? x : y); }  Define the function explicitly for char * template<> char * min <char *>(char *x, char *y) { return ((strcmp(x, y) < 0) ? x : y); } Jan 2014 174OOP in C++
  • 175.
    A List TemplateClass template<class T> class List { public : List (); virtual ~List (); int put (const T &val); T *unput (); T *get (); int unget (const T &val); T *find(const T &val); int length (); private: struct Node { Node *next_item; T *list_item; } *beg_ptr; *end_ptr; int how_many; }; template<class T> int List<T>:: put (const T &val) { Node *tmp_ptr = new Node; if (tmp_ptr && (tmp_ptr->list_item = new T (val) ) ) { tmp_ptr->next_item = 0; if (end_ptr) end_ptr->next_item = tmp_ptr; else beg_ptr = tmp_ptr; end_ptr = tmp_ptr; how_many++; return 1; } else return 0; } Jan 2014 175OOP in C++
  • 176.
    Using a TemplateClass int main () { register int i, *iptr; String *sptr; char *somedata [] = {“one”, “two”, “three”, “four”, “five”, “six”, “seven”, “eight”, “nine”, “ten”}; List<int> ii; List<String> is; for (i = 1; i <=10; i++) { ii.put(i); } cout << “The List<int> contains “ ; cout << ii.length () << “ itemsn” ; return 0; } Jan 2014 176OOP in C++
  • 177.
    Parameterized Class  Aclass template  describes how a class should be built  Supplies the class description and the definition of the member functions using some arbitrary type name, (as a place holder).  is a parameterized type with parameterized member functions Jan 2014 177OOP in C++
  • 178.
    Parameterized Class  canbe 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, (i.e. type), parameters  is often used for “container” classes Jan 2014 178OOP in C++
  • 179.
    Parameter Requirements Parameter Types may be of any type, (including user defined types)  may be parameterized types, (i.e. 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 ? Jan 2014 179OOP in C++
  • 180.
    Class Template Instantiation Class Template is instantiated only when it is required.  Matrix is a class template  Matrix m; //error  Matrix *pm; // OK  void inverse (Matrix & m); //OK  Class template is instantiated before  An object is defined with class template instantiation  If a pointer or a reference is de-referenced (e.g., 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 2014 180OOP in C++
  • 181.
    Friend & StaticDeclaration  There are 3 kinds of friend declarations  Non-template friend.  A bound friend class template.  One-to-one mapping between the instance of a class template and its friend  An unbound friend class template.  One-to-many mapping between the instance of a class template and its friend  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. Jan 2014 181OOP in C++
  • 182.
    Source code organization Inclusion Model  Make the template definition visible to compiler at the point of instantiation  Include source files as well.  Increase in build and link time  Instantiate the types you need explicitly in a separate compile unit.  Cannot use benefits of lazy instantiation.  Separation Model  Use keyword ‘export’ in front of definition.  Not many compiler supports the feature. Jan 2014 182OOP in C++
  • 183.
    Template specialization  Allowsto make specific implementation when pattern is of determined type.  The syntax is template<> class XXX<Type> {..}  No member is ‘inherited’ from the generic template to specialized one. So, must define ALL members equating them to specialization  Class templates can be partially specialized too.  A totally disjoint template that the compiler gives a priority while instantiation. Jan 2014 183OOP in C++
  • 184.
    Templates & Derivation A template expresses a commonality across types  Two types generated from a common template are different.  A Base class expresses commonality of representation and calling interface.  Example  template <class T, class A> class specalContainer : public Container<T>, A;  specialContainer<Node, Fast_Allocator> s;  specialContainer<Node, Shared> s1;  specialContainer<ProcessDescriptor, Fast_Allocator> p;Jan 2014 184OOP in C++
  • 185.
    Template Inheritance: ABase Template template<class T> class set { public : Set ( ) { } ; virtual void add (const T &val); int length ( ) ; int find (const T &val); private: List<T> items; }; template<class T> void Set<T> : : add (const T &val) { if (items.find (val) ) return; items.put (val) ; } template<class T> int Set<T> : : length ( ) { return items.length ( ) ; } template<class T> int Set<T> ::find (const T &val) { return (int) items.find(val); } Jan 2014 185OOP in C++
  • 186.
    Template Inheritance: A DerivedTemplate /* boundset.h */ #include “set.h” template<class T> class BoundSet : public Set<T> public: BoundSet (const T &lower, const T &upper); void add(const T &val); private: T min; T max; }; template<class T> BoundSet<T>:: BoundSet (const T &lower, const T &upper) : min (lower), max (upper) { } template<class T> void BoundSet<T> : :add(const T &val) { if (find (val) ) return; if ( (val <= max) && (val >= min) ) Set<T>: : add (val) ; } Jan 2014 186OOP in C++
  • 187.
    Using a DerivedTemplate Class int main ( ) { register int i ; BoundSet<int> bsi (3, 21); Set<int> *Setptr = &bsi; for (i = 0; i < 25; i++) setptr->add( i ) ; if (bsi.find (4) cout << “We found an expected valuen”; if (bsi.find (0) || bsi.find(25 ) ) { cout << “We found an Unexpected valuen”; return 23; } else cout << “We found NO unexpected valuen”; return 0; } Jan 2014 187OOP in C++
  • 188.
    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.  Compiler view  Constructor of objects containing virtual functions must initialize the vptr table.  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 2014 188OOP in C++
  • 189.
    Inheritance vs Templates: Example Implementthe following command. # ECHO infile outfile main() { (argc > 2 ? ofstream (argv[2] ,ios::out) : cout) << (argc > 1 ? ifstream (argv[1], ios::in) : cin) .rdbuf(); } main() { fstream in, out; if (argc > 1) in.open(argv[1], ios::in); if (argc > 2) out.open(argv[2], ios::out); Process(in.is_open() ? in : cin, out.is_open() ? out : cout); }  How to implement ‘Process’ ?  Two ways to get the polymorphic behavior  virtual function and templates Jan 2014 189OOP in C++
  • 190.
    Inheritance vs Templates: Solution template<typenameIn, typename out> void process(In& in, Out& out) { // out << in.rdbuf(); }  Merely requires that the passed objects to have suitable interface (such as member function named rdbuf(). ) void Process (basic_istream& in, basic_ostream& out) { // out << in.rdbuf(); }  Requirement:  cin and ifstream both derived from basic_istream  The common base class ‘basic_istream has suitable interface ‘rdbuf’.  Both Methods solve the current problem.  But templates provide extensibility.  Other streams can be provided with rdbuf() interface.  Other streams cannot be guaranteed to be derived from the same base class Jan 2014 190OOP in C++
  • 191.
    Another Example  Acollection of classes is required for  Stack: for ints , strings, floats etc.  Has operations: push, pop, length of stack.  transportationMode . For airplane, car, boat etc.  Has features : move, comfort etc  each move in diff ways.  Each provide different level of comfort.  Analyze if the ‘type’ being manipulated has any affect on the behavior of class .  If ‘type’ does not affect the behavior, use templates  If ‘type’ affects the behavior, use virtual functions (inheritance) Jan 2014 191OOP in C++
  • 192.
  • 193.
    Jan 2014 OOPin C++ 193 Ranking of Programming Languages in Jan 2014 TIOBE Index for January 2014 Jan-14 Jan-13Change Programming Language Ratings Change 1 1 = C 17.87% 0.02% 2 2 = Java 16.50% -0.92% 3 3 = Objective-C 11.10% 0.82% 4 4 = C++ 7.55% -1.59% 5 5 = C# 5.86% -0.34% 6 6 = PHP 4.63% -0.92% 7 7 = (Visual) Basic 2.99% -1.76% 8 8 = Python 2.40% -1.77% 9 10 + JavaScript 1.57% -0.41% 10 22 + Transact-SQL 1.56% 0.98% 11 12 + Visual Basic .NET 1.56% 0.52% 12 11 – Ruby 1.08% -0.69% 13 9 – Perl 0.92% -1.35% 14 14 = Pascal 0.78% -0.15% 15 17 + MATLAB 0.78% 0.14% 16 45 + F# 0.72% 0.53% 17 21 + PL/SQL 0.63% 0.05% 18 35 + D 0.63% 0.33% 19 13 – Lisp 0.60% -0.35% 20 15 – Delphi/Object Pascal 0.60% -0.32% http://www.tiobe.com/index.php/content/paperinfo/tpci/index.html
  • 194.
    Jan 2014 OOPin C++ 194