8/19/2019 SE - Lecture 03-30 [OOP in C++]
1/217
Object-Oriented
Programming in C++
Jan-Feb 2016
Lecture 03-
Prof. Partha Pratim Das
S20006: Software Engineering
8/19/2019 SE - Lecture 03-30 [OOP in C++]
2/217
PROGRAMMING IN C++
Object-Oriented Modeling & Programming
Jan-Feb 2016 2
8/19/2019 SE - Lecture 03-30 [OOP in C++]
3/217
Topics
Procedural Enhancements in C++ over C
Classes
Overloading
Inheritance Type Casting
Exceptions
Templates
Jan-Feb 2016 3
8/19/2019 SE - Lecture 03-30 [OOP in C++]
4/217
PROCEDURALENHANCEMENTS IN C++
Object Oriented Programming in C++
Jan-Feb 2016 4
8/19/2019 SE - Lecture 03-30 [OOP in C++]
5/217
TOPICS
Const-ness
Reference Data Type
Inline Functions
Default Function Parameters Function Overloading & Resolution
Dynamic Memory Allocation
Jan-Feb 2016 5
8/19/2019 SE - Lecture 03-30 [OOP in C++]
6/217
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 cannot point toa const object;const double d = 5.6;
double *p = &d; //error
Pointer to a constant object vs. constant pointerto an object.const double * pConstantObject;
double * const *pConstantPointer;
Jan-Feb 2016 6
8/19/2019 SE - Lecture 03-30 [OOP in C++]
7/217
References
A reference is an additional name / alias
/ synonym for an existing variable Declaration of a Reference
& = ;
Examples of Declarationint j = 5;
int& i = j;
Jan-Feb 2016 7
8/19/2019 SE - Lecture 03-30 [OOP in C++]
8/217
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
Jan-Feb 2016 8
8/19/2019 SE - Lecture 03-30 [OOP in C++]
9/217
References Do not ..
Cannot have an array of references
No operator other than initialization are valid on areference. 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 thereferent.
Jan-Feb 2016 9
8/19/2019 SE - Lecture 03-30 [OOP in C++]
10/217
Call-by-Reference
Calling by Reference
Parameters can be passed byreference w/o copy
A reference parameter is an in-outparameter (read-write)
Recall: A call-by-value parameter is
an input parameter A const reference parameter is an
input only parameter (read-only)
Jan-Feb 2016 10
8/19/2019 SE - Lecture 03-30 [OOP in C++]
11/217
Call-by-Reference
Thumb Rules
Pass parameters of built-in types byvalue
Recall: Array parameters are passedby reference in C
Pass parameters of user-defined
types by reference Make a reference parameter const if it
is not used for output
Jan-Feb 2016 11
8/19/2019 SE - Lecture 03-30 [OOP in C++]
12/217
Returning a Reference
Returning a reference
return value is not copied back
may be faster than returning a value
calling function can change returnedobject
cannot be used with local variables
Jan-Feb 2016 12
8/19/2019 SE - Lecture 03-30 [OOP in C++]
13/217
Example
Jan-Feb 2016 13
8/19/2019 SE - Lecture 03-30 [OOP in C++]
14/217
Returning a Reference
#include
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
8/19/2019 SE - Lecture 03-30 [OOP in C++]
15/217
Pointers vs. References
Pointers can point to NULL whereas References
cannot. There is nothing defined as NULLReference.
Pointers can point to different variables atdifferent 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 notstore that address. Pointer does.
Jan-Feb 2016 15
8/19/2019 SE - Lecture 03-30 [OOP in C++]
16/217
Macros
Macros are expanded at the places of their calls.
Advantages: Speed-wise efficient
Disadvantages:
Parameter passing mechanism is not robust andfrequently leads to errors.
Type checking during parameter passing is not done
Code size tend to increase
Typical Use: Small code re-use
Jan-Feb 2016 16
8/19/2019 SE - Lecture 03-30 [OOP in C++]
17/217
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/.cxxfiles
Jan-Feb 2016 17
8/19/2019 SE - Lecture 03-30 [OOP in C++]
18/217
Inline Notes
inline specification is only a
recommendation. A recursive or a large function may not
be inline.
Unlike a non-inline function, an inlinefunction must be defined in every textfile where it is called.
Inline functions must not have twodifferent definitions. May cause unexpected behavior if compiler
does not chose to make the function inline.
Jan-Feb 2016 18
8/19/2019 SE - Lecture 03-30 [OOP in C++]
19/217
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 withdefault argument must have default arguments.
Default arguments cannot be re-defined.
Default parameters should be supplied only in aheader file and not in the definition of a function.
Jan-Feb 2016 19
8/19/2019 SE - Lecture 03-30 [OOP in C++]
20/217
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 declarationff(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(int i, float f = 0.0, char ch); //OK
ff(int i = 0, float f, char ch); //OK
Jan-Feb 2016 20
8/19/2019 SE - Lecture 03-30 [OOP in C++]
21/217
Function Overloading
The same function name may be used in several definitions.
Functions with the same name must have different number offormal parameters and/or different types of formalparameters.
Function selection based on number and types of the actualparameters at the places of invocation.
Function selection (Overload Resolution) is performed by thecompiler
Two functions having the same signature but different returntypes will result in a compilation error due to “attempt to re-declare”.
Overloading allows static polymorphism
Jan-Feb 2016 21
8/19/2019 SE - Lecture 03-30 [OOP in C++]
22/217
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
Jan-Feb 2016 22
8/19/2019 SE - Lecture 03-30 [OOP in C++]
23/217
Overload Resolution
Steps to resolve overloaded functionswith 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
Jan-Feb 2016 23
8/19/2019 SE - Lecture 03-30 [OOP in C++]
24/217
Exact Match
lvalue-to-rvalue conversion
Most common
Array-to-pointer conversionDefinitions: int ar[10]; void f(int *a);
Call: f(ar)
Function-to-pointer conversionDefinitions: typedef int (*fp) (int);
void f(int x, fp); int g(int);
Call: f(5, g)
Qualification conversion Converting p o i n t e r ( o n l y ) to const pointer.
Jan-Feb 2016 24
8/19/2019 SE - Lecture 03-30 [OOP in C++]
25/217
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
Jan-Feb 2016 25
8/19/2019 SE - Lecture 03-30 [OOP in C++]
26/217
Jan-Feb 2016
int f(int, int)
{ cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
27/217
Examples of Resolution
int main() {
int a = 2, b = 3, *q = &a;
char *p = 0; double d = 5.2;
f(a, b);
// int f(int, int)
f(a, p);
// void f(int, char *)f(a);
// double f(int)
f(d);
// int f(double)
f();
// void f()
Jan-Feb 2016
int f(int, int);
void f(int, void *);
void f(int, char *);
double f(int);
int f(double);
void f();
void f(int[]);
typedef void (*fp) (int);void f(int x, fp);
void g(int) {}
void h(int) {}
27
8/19/2019 SE - Lecture 03-30 [OOP in C++]
28/217
Examples of Resolution
int main() {
int a = 2, b = 3, *q = &a;
char *p = 0; double d = 5.2;
...
f(4, 5);
// int f(int, int)
f(8, q);// void f(int, void *)
f(7);
// double f(int)
f(7.0);
// int f(double)
f(4.6, 5);
// int f(int, int)
Jan-Feb 2016
int f(int, int);
void f(int, void *);
void f(int, char *);
double f(int);
int f(double);
void f();
void f(int[]);
typedef void (*fp) (int);void f(int x, fp);
void g(int) {}
void h(int) {}
28
8/19/2019 SE - Lecture 03-30 [OOP in C++]
29/217
8/19/2019 SE - Lecture 03-30 [OOP in C++]
30/217
Overload Resolution withconst, reference & expression
T1, T2 int constint
int& const int&
int X redef error
int a, b;f(a); //f(a+b); //f(7); //
int a, b;f(a); //f(a+b); //f(7); //
const int - X int a, b;f(a); //f(a+b); //f(7); //
int a, b;f(a); //f(a+b); //f(7); //
int& - - X int a, b;f(a); //f(a+b); //f(7); //
const int& - - - X
Jan-Feb 2016
void f(T1); void f(T2);
30
8/19/2019 SE - Lecture 03-30 [OOP in C++]
31/217
Overload Resolution withconst, reference & expression
T1, T2 int constint
int& const int&
int X redef error
int a, b;f(a); // ambiguousf(a+b); // ok – intf(7); // ok – int
int a, b;f(a); // ambiguousf(a+b); // ambiguousf(7); // ambiguous
const int - X int a, b;f(a); // ambiguousf(a+b); // ok – const intf(7); // ok – const int
int a, b;f(a); // ambiguousf(a+b); // ambiguousf(7); // ambiguous
int& - - X int a, b;f(a); // ok – int& f(a+b); // ok – const int & f(7); // ok – const int &
const int& - - - X
Jan-Feb 2016
void f(T1); void f(T2);
31
8/19/2019 SE - Lecture 03-30 [OOP in C++]
32/217
Overload Resolution withconst – int & double
T1, T2 double
int int a;f(a); //f(7); //
const int int a;f(a); //f(7); //
int& int a;f(a); //f(7); //
const int& int a;f(a); //f(7); //
Jan-Feb 2016
void f(T1);
void f(T2);
32
8/19/2019 SE - Lecture 03-30 [OOP in C++]
33/217
Overload Resolution with
const – int & double
T1, T2 double
int int a;f(a); // ok – intf(7); // ok – int
const int int a;f(a); // ok – const int
f(7); // ok – const int
int& int a;f(a); // ok – int& f(7); // ok – double
const int& int a;f(a); // ok – const int& f(7); // ok – const int&
Jan-Feb 2016
void f(T1);void f(T2);
33
8/19/2019 SE - Lecture 03-30 [OOP in C++]
34/217
Operator & Operator Function
What is the difference between an
operator and a function? Notation!
Operator:
Infix: a + b; a ? b : c;
Prefix: ++a;
Postfix: a++;
Function: Prefix: max(a, b);
qsort(int[], int, int, void (*)(void*, void*));Jan-Feb 2016 34
8/19/2019 SE - Lecture 03-30 [OOP in C++]
35/217
Operator & Operator Function
Every operator has a function that
defines its behaviour – implicit forpredefined operators of built-in types
For example, for int a = 2, b = 3, c;
c = a + b;
is equivalent to:
int operator+(int x, int y);
c = operator+(a, b);
Jan-Feb 2016 35
8/19/2019 SE - Lecture 03-30 [OOP in C++]
36/217
Operator & Operator Function
C++ allows you to define your
operator’s function & overload it Operators for built-in types cannot be
redefined
Jan-Feb 2016 36
8/19/2019 SE - Lecture 03-30 [OOP in C++]
37/217
Overload Operator+
Jan-Feb 2016
#include
using namespace std;
enum E {C0 = 0, C1 = 1, C2 = 2};
int main() {
E a = C1, b = C2;
int c = -1;
c = a + b;
cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
38/217
Overload Operator+
Jan-Feb 2016
#include
using namespace std;
enum E {C0 = 0, C1 = 1, C2 = 2};
E operator+(const E& a, const E& b) {
unsigned int uia = a, uib = b;
unsigned int t = (uia + uib) % 3;
return (E) t;
}
int main() {
E a = C1, b = C2;
int c = -1;
c = a + b;
cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
39/217
Examples of Resolution
(Conflict)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?
}
Jan-Feb 2016
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?
}
39
8/19/2019 SE - Lecture 03-30 [OOP in C++]
40/217
8/19/2019 SE - Lecture 03-30 [OOP in C++]
41/217
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.
Jan-Feb 2016 41
8/19/2019 SE - Lecture 03-30 [OOP in C++]
42/217
CLASS
Object Oriented Programming in C++
Jan-Feb 2016 42
8/19/2019 SE - Lecture 03-30 [OOP in C++]
43/217
TOPICS
Class Members
Constructor & Destructor
Friends
Static Members Struct & Union
Jan-Feb 2016 43
8/19/2019 SE - Lecture 03-30 [OOP in C++]
44/217
Class C++ Class is an implementation of “type”
In C++, class is the only way to implement userdefined data types
A C++ class contains data members/attributes tospecify the state and operations/methods to specify
the behavior Thus, classes in C++ are responsible to offer
needed data abstraction/encapsulation of ObjectOriented Programming
C++ Classes also provide means (through accessspecifier) to enforce data hiding that separatesimplementation from interface
Jan-Feb 2016 44
8/19/2019 SE - Lecture 03-30 [OOP in C++]
45/217
Class A Class is defined by “class” keyword
Each member in a class has an access specifier private – accessible inside the definition of the
class
public – accessible everywhere
Objects/instances of classes are to be createdstatically or dynamically
Members can be accesses by “.” operator on theobject
The implicit this pointer holds the address of anyobject.
this pointer is implicitly passed to methods.Jan-Feb 2016 45
8/19/2019 SE - Lecture 03-30 [OOP in C++]
46/217
A Simple Class
Jan-Feb 2016
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
e1.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); }
46
8/19/2019 SE - Lecture 03-30 [OOP in C++]
47/217
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);
}
Jan-Feb 2016 47
8/19/2019 SE - Lecture 03-30 [OOP in C++]
48/217
Constructor Functions
Constructor functions:
are member functions with the same nameas the class
are automatically called when an object iscreated, just after memory allocation
In case of auto/static variables, objects are created inthe stack/static Store when their definition isencountered
Objects can be created in the Free store with a pointer
storing the address.
allow the class to initialise the state of anobject
Jan-Feb 2016 48
8/19/2019 SE - Lecture 03-30 [OOP in C++]
49/217
Constructor Functions
Constructor functions:
Constructors also allocate additionalmemory space from the Free store (if)required for the object
Must not have any return type even void
Default constructors are those constructorswhich either do not have an argument orhave default arguments for all parameters
If users do not define any constructor thenthe compiler provides a default constructor
Jan-Feb 2016 49
8/19/2019 SE - Lecture 03-30 [OOP in C++]
50/217
Additional Constructor Functions
Constructor function can be overloaded
Constructor functions can be directlycalled to create anonymous objects Calling a constructor from a constructor
does not have the desired effect
If there is at least one definition ofconstructor but no default constructorthen the following statements areincorrect
X a; X *pX = new X();
Jan-Feb 2016 50
8/19/2019 SE - Lecture 03-30 [OOP in C++]
51/217
Destructor Functions
Destructor function:
is a member function named “~ ” (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” inthe constructor
Jan-Feb 2016 51
8/19/2019 SE - Lecture 03-30 [OOP in C++]
52/217
Copy Constructor
Copy constructor is a special
constructor which is used to initialize anobject with another object of the sametype.
Copy constructor of class X takes anargument of type X&.
If the type of argument is X in stead of X&,an infinite loop results.
Jan-Feb 2016 52
8/19/2019 SE - Lecture 03-30 [OOP in C++]
53/217
8/19/2019 SE - Lecture 03-30 [OOP in C++]
54/217
A Sample Class : String
Jan-Feb 2016 54
class String {
public:
String();
String(const String&); // Copy Constructor
String(const char *);
~String();
int length();
int read();
void print();
private:
char *data;
int len;
}
Class String::Constructor &
8/19/2019 SE - Lecture 03-30 [OOP in C++]
55/217
Class String::Constructor &
DestructorSt r i ng: : St r i ng( ) {
dat a = NULL;
l en = 0;}
St r i ng: : St r i ng( const char *s) {
dat a = new char [ st r l en( s) +1] ;
l en = st r l en( s) ;
st r cpy( dat a, s) ;
}
voi d ~St r i ng( ) {
i f ( dat a ! = NULL)
del et e [ ] dat a;
}
i nt mai n( )
{
St r i ng s1; / / def aul t const r uct orSt r i ng s11( ) ; / / Er r or
St r i ng s1( “t est ”) ;
char str[6];
str cpy( str , “Hel l o”) ;
St r i ng s2( str ) ;
St r i ng s3( s2) ; / / Copy Const r uct or
St r i ng s4 = new St r i ng( “one”) ;
St r i ng s5 = new St r i ng( ) ;
del et e s4;
del et e s5;
}
Jan-Feb 2016 55
8/19/2019 SE - Lecture 03-30 [OOP in C++]
56/217
Arrays
Using Default constructor while
creating an array of objects St r i ng ar r ayOf St r i ng[ 100] ; / / 100 obj ect s cr eat ed usi ng t he
def aul t const r uct or
Using specialized constructor while
creating an array of objects. St r i ng ar r ayOf St r i ng[ 2] = { St r i ng( “abc”) , St r i ng( “def ”) };
Using different constructor for creating
array objects dynamically. St r i ng *pAr r ayOf St r i ng[ 2] =
{ new St r i ng( “abc”) , new St r i ng( “def ”) };
Jan-Feb 2016 56
8/19/2019 SE - Lecture 03-30 [OOP in C++]
57/217
Copy Assignment Operator
Bug:
The following assignment cannot bemade String x(“abc”), y(“def”), z(“ghi”);
x = y = z;
(x.operator=((y).operator=(z)));
Solution
Change the return type to String &
Jan-Feb 2016
String a(“123”), b(“456”);
b = a; // b.operator=(a);
String String::operator=(const String& rhs)
{
len = rhs.len;
data = new char[len + 1];
strcpy(data, rhs.data);
return *this ;
}
class String {
public:
String();String(const String&);
String(const char *);
~String();
int length();
int read();
void print();
private:
char *data;
int len;
}
57
8/19/2019 SE - Lecture 03-30 [OOP in C++]
58/217
Copy Assignment Operator
Bug:
Memory Leak as
previous data of this isnot deleted.
Jan-Feb 2016
String a(“123”), b(“456”);
b = a; // b.operator=(a);
String& String::operator=(const String& rhs) {
len = rhs.len;
data = new char[len + 1];
strcpy(data, rhs.data);
return *this ;
}
String a(“123”), b(“456”);
b = “123”; // b.operator=(“123”);
String& String::operator=(const char *rhs) {
len = strlen(rhs);data = new char[len + 1];
strcpy(data, rhs);
return *this ;
}
58
8/19/2019 SE - Lecture 03-30 [OOP in C++]
59/217
8/19/2019 SE - Lecture 03-30 [OOP in C++]
60/217
Copy Assignment Operator
Jan-Feb 2016
String& String::operator=(const String& rhs)
{
if (this != rhs) {
len = rhs.len;
delete [] data;
data = new char[rhs.len + 1];
strcpy(data, rhs.data);
}
return *this ;
}
60
More On “=” Operator
8/19/2019 SE - Lecture 03-30 [OOP in C++]
61/217
More On = Operator
Overloading There is a system defined implementation of
assignment operator. In absence of user definedassignment operator function, systems’ function isused.
System defined function makes a shallow copy.
Some times shallow copying may be dangerous
If the constructor uses new, assignment operatormay have to be overloaded.
If there is a need to define a copy constructor thenthere must be a need to overload assignmentoperator and vice-versa.
Jan-Feb 2016 61
8/19/2019 SE - Lecture 03-30 [OOP in C++]
62/217
Object Layout Simplistically, an object
of a class must have
enough space to store allmembers of that class.
No space is required perobject for storing functionpointers for the methods
declared in the class. Methods on objects are
translated by thecompiler to C-likefunction calls by passing
this pointer.
A String Object
data
len
H e l l o \n
Jan-Feb 2016 62
8/19/2019 SE - Lecture 03-30 [OOP in C++]
63/217
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.
Jan-Feb 2016 63
8/19/2019 SE - Lecture 03-30 [OOP in C++]
64/217
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
Jan-Feb 2016 64
8/19/2019 SE - Lecture 03-30 [OOP in C++]
65/217
Class Member: Notes It is always a good idea to define data members as
“private”.
Composition through objects are preferred overComposition 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 orpointer to less accessible data
Defeats basic data hiding philosophy. May also lead to stunning consequences.
Jan-Feb 2016 65
8/19/2019 SE - Lecture 03-30 [OOP in C++]
66/217
Const Member Functions Constant Member Functions
are not allowed to change
the state of the object onwhich they are invoked.
Const Functions are declaredwith keyword const followingmember function parameter
list. const must also be present
at the definition.
Type of this pointer passedto a const function is
const X* const this
cl ass X {
pr i vat e:
i nt i pr i v;
publ i c:
i nt i pub;
i nt f ( ) const ;
};
i nt X: : f ( ) const
{
i nt t emp;
t emp = i pr i v + i pub; / / accessi ng members OK
i pr i v += t emp; / / cannot modi f y any member
i pub - = t emp; / / cannot modi f y any member}
Jan-Feb 2016 66
8/19/2019 SE - Lecture 03-30 [OOP in C++]
67/217
Friend Functions
Friend functions
are declared in one or more classes
have access to the private members ofthose classes
are distinguished from members withthe keyword friend
are not called with an invoking objectof those classes
Jan-Feb 2016 67
8/19/2019 SE - Lecture 03-30 [OOP in C++]
68/217
Friend Functions: Examplecl ass St r i ng {
publ i c :
St r i ng( ) ;
St r i ng( const char *) ;St r i ng( i nt l en) ;
f r i end St r i ng concat ( St r i ng*, St r i ng*) ;
f r i end St r i ng concat ( St r i ng*, char *) ;
f r i end St r i ng concat ( char *, St r i ng*) ;
pr i vat e :
char *dat a;
i nt l en;} ;
St r i ng: : St r i ng( i nt l en)
{
t hi s- >l en = l en;
dat a = new char [ l en+1] ;
dat a[ l en] = ‘ \ 0’ ;
}
St r i ng concat ( St r i ng * l ef t , St r i ng *r i ght )
{
St r i ng bot h[ l ef t - >l en + r i ght - >l en + 1] ;
st r cpy( bot h. dat a, l ef t - >dat a) ;
st r cat ( bot h. dat a, r i ght - > dat a) ;
r et ur n bot h;
}
St r i ng concat ( char *l ef t , St r i ng *r i ght )
{St r i ng bot h[ st r l en( l ef t ) + r i ght - >l en + 1] ;
str cpy( bot h. dat a, l ef t ) ;
st r cat ( bot h. dat a, r i ght - >dat a) ;
r et ur n bot h;
}
Jan-Feb 2016 68
8/19/2019 SE - Lecture 03-30 [OOP in C++]
69/217
Friends of More Than One classcl ass Mat r i x; / / For war d decl ar at i on t o make
/ / decl ar at i on of crosspr od l egalcl ass Vect or {
publ i c :Vector ( i nt n) ;f r i end Vect or pr od( Mat r i x *pM, Vect or *pV) ;
pr i vat e :i nt el ement s[ 10] ;i nt n;
};
cl ass Mat r i x {publ i c :
Mat r i x( i nt m, i nt n) ;f r i end Vect or pr od( Mat r i x *pM, Vect or *pV) ;
pr i vat e :i nt el ement s[ 10] [ 10] ;i nt m, n;
};
Vector pr od( Mat r i x *pM, Vect or *pV)
{
i nt V( pM- >m) ;
f or ( i = 0; i < pM- >m; i ++)f or ( j = 0; j < pM- >n; j ++)
{
v[ i ] += pM- >el ement s[ i ] [ j ] *
pV- >el ement s[ i ] ;
}
}
Jan-Feb 2016 69
8/19/2019 SE - Lecture 03-30 [OOP in C++]
70/217
Friend Members & Class Member of a different class
may be a friend function.
A class may be declared as afriend implying all memberfunctions of that class arefriends.
Friend-ship is neithercommutative nor transitive.
Friends tend to break datahiding.
It is best to avoid friend in
an ideal OO Design.
cl ass Mat r i x;
cl ass Vect or {
publ i c:
voi d Vect or ( i nt n) ;Vect or prod( Mat r i x *pM) ;
i nt el ement s[ 10] ;
i nt n;
} ;
cl ass Mat r i x {
publ i c:voi d Mat r i x( i nt m, i nt n) ;
f r i end Vect or Vect or : : pr od( Mat r i x *pM) ;
pr i vat e:
i nt el ement s[ 10] [ 10] ;
i nt m, n;
} ;
Jan-Feb 2016 70
8/19/2019 SE - Lecture 03-30 [OOP in C++]
71/217
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 sourcefile.
It can be accessed
with the class-name
followed by the scoperesolution operator “::”
as a member of anyobject of the class
X. h
- - -
cl ass X {
publ i c:
s tat i c i nt count ; / / Thi s i s adecl ar at i on
X( ) { count ++; }
}
X. cxx
- - - - -
#i ncl ude “X. h”i nt X: : count = 0; / / Def i ni t i on & I ni t i al i zat i on
i nt mai n( )
{
X a, b, c;
pr i nt f ( “%d %d %d %d\ n”, X: : count , a. count ,
b. count , c. count ) ;
}
The output will be 3 3 3 3
Jan-Feb 2016 71
8/19/2019 SE - Lecture 03-30 [OOP in C++]
72/217
Static Data: A Listcl ass Li st Node {
publ i c:
s tat i c Li s tNode * f i rs t ;
pr i vat e:
Li st Node *next ;
i nt dat a;
publ i c:
Li st Node( i nt x) ;
pr i nt ( ) ;
}
Li st Node *Li st Node: : f i r st = NULL;Li st Node: : Li st Node( i nt x) {
dat a = x;
next = NULL;
i f ( f i r st == NULL)
f i r s t = t hi s ;
el se
{
next = f i r st ;
f i r s t = t hi s ;
}
}
voi d Li st Node: : pr i nt ( ) {
Li st Node *x;
x = Li st Node: : f i r st ;
whi l e ( x ! = NULL)
{
pr i nt f ( “%d “, x- >dat a) ;
x = x- >next ;
}
pr i nt f ( “\ n”) ;
}
i nt mai n( ) {
Li st Node x( 5) ;
Li st Node x( 7) ;
Li st Node x( 8) ;
x. pr i nt ( ) ;
}
The output will be 8 7 5
Jan-Feb 2016 72
8/19/2019 SE - Lecture 03-30 [OOP in C++]
73/217
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 staticfunction
must not refer to non-static members ofits “invoking object”
Philosophy of static members.
Jan-Feb 2016 73
Static Members in Inline
8/19/2019 SE - Lecture 03-30 [OOP in C++]
74/217
Functions Not SafeX. hxx
Cl ass X{
publ i c:
s tat i c voi d f ( ) ;
s tat i c St r i ng g( ) ;
pr i vat e:
st at i c St r i ng s;}
i nl i ne St r i ng X: : g( )
{
/ / do some operat i on on s
return s;
}
X. cxx
#i ncl ude “X. hxx”
voi d X: : f ( )
{
X: : g( ) ;
}
The above code will not fail;The code in the followingmay fail however.
X1. cxx
#i ncl ude “X. hxx”
i nt mai n( )
{
X: : g( ) ;
}
Data members areguaranteed to beinitialized before any non-inline function is called.
Jan-Feb 2016 74
8/19/2019 SE - Lecture 03-30 [OOP in C++]
75/217
OPERATOR OVERLOADING
Object Oriented Programming in C++
Jan-Feb 2016 75
8/19/2019 SE - Lecture 03-30 [OOP in C++]
76/217
8/19/2019 SE - Lecture 03-30 [OOP in C++]
77/217
Overloading Operators Example Let ‘+’ denote concatenation for Strings.
“s1 + s2” denote concatenation of strings s1and s2.
An expression of the form “s1+s2” is
converted to s1.operator+(s2) if there is afunction named “operator+” defined in theclass String.
“s1+s2” is also equivalent to operator+(s1,
s2) if a global function named “operator+” isproperly defined; typically such globalfunctions are friends to the class String.
Jan-Feb 2016 77
Example of overloading
8/19/2019 SE - Lecture 03-30 [OOP in C++]
78/217
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);
}
Jan-Feb 2016 78
8/19/2019 SE - Lecture 03-30 [OOP in C++]
79/217
Reference & Overloading Suppose that we have a
class Integer which has a
private data member asint . The followingfunction is declared as afriend of Integer .
Integer & operator*(Integer &lhs,Integer &rhs) {
Integer result = lhs.data *rhd.data;
return result;
}
Problem: Returningreference to a localobject. 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 followinguse?
Integer a(1), b(2), c(3),
d(3);Integer e =
a*b*c*d;
Jan-Feb 2016 79
8/19/2019 SE - Lecture 03-30 [OOP in C++]
80/217
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);
Jan-Feb 2016 80
8/19/2019 SE - Lecture 03-30 [OOP in C++]
81/217
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 bechanged by overloading an operator.
Conditional Operators like &&, ||, comma
operator should not be overloaded.
Jan-Feb 2016 81
8/19/2019 SE - Lecture 03-30 [OOP in C++]
82/217
Friends vs Methods Members are better in terms of restriction of
scope which results in efficient searching forbest function to resolve overloading.
Members will not help if the left hand side of theoperator is not of the class type.
String s1 = “abc” + s2; // may be wrong
In case of overloading stream operators, weneed friend due to the reason stated above.
Resolving in case of a conflict between friendand method.
Jan-Feb 2016 82
8/19/2019 SE - Lecture 03-30 [OOP in C++]
83/217
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, thefollowing is valid.
Rational a, b, c;(a * b) = c;
Retuning const ensures that overloaded “*” iscompatible with the same operator on built-intypes.
Jan-Feb 2016 83
8/19/2019 SE - Lecture 03-30 [OOP in C++]
84/217
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
8/19/2019 SE - Lecture 03-30 [OOP in C++]
85/217
const
What should a constant member
function preserve? Bit-wise const-ness
Conceptual const-ness
Bit-wise const member functions maybecome unsafe.
Conceptual const member function may
need to change some bits of the object mutable keyword.
Jan-Feb 2016 85
8/19/2019 SE - Lecture 03-30 [OOP in C++]
86/217
INHERITANCE
Object-Oriented Programming in C++
Jan-Feb 2016 86
8/19/2019 SE - Lecture 03-30 [OOP in C++]
87/217
Topics Fundamentals of Inheritance
protected Access Specifier Initialization
Virtual Functions
Jan-Feb 2016 87
R bilit
8/19/2019 SE - Lecture 03-30 [OOP in C++]
88/217
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-Feb 2016 88
B i f C I h it
8/19/2019 SE - Lecture 03-30 [OOP in C++]
89/217
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 baseclass 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 andbehavior of the base class by adding moreattributes and methods.
Jan-Feb 2016 89
Accessibility of Base Class
M b
8/19/2019 SE - Lecture 03-30 [OOP in C++]
90/217
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 thebase class become private members of the
derived class and public members of the baseclass become public members of the derivedclass
However, private members of the base classare not directly accessible to the members inthe derived class.
Jan-Feb 2016 90
Obj t L t i I h it
8/19/2019 SE - Lecture 03-30 [OOP in C++]
91/217
Assume thefollowing classhierarchy
class C: public B
{ .. };
class B: public A
{ .. };
class A
{ .. };
Object Layout in InheritanceLayout for an objectof type C
A-Part Data Member
B-Part Data Member
C-Part Data Member
Jan-Feb 2016 91
t t d M b
8/19/2019 SE - Lecture 03-30 [OOP in C++]
92/217
protected Members private data members of the base class
cannot be directly accessed by themethods of the derived class.
However, it is important for the derivedclass to have more accessibility to themembers of the base class than otherclasses or functions.
If a member is protected then it isdirectly accessible to the methods of thederived class.
Jan-Feb 2016 92
Syntax of Inheritance
8/19/2019 SE - Lecture 03-30 [OOP in C++]
93/217
Syntax of Inheritance An example
cl ass Empl oyee {pr ot ect ed:
f l oat basi c;l ong i d;publ i c:Empl oyee( l ong i d) ;f l oat get Sal ar y( ) ;
};
cl ass Manager : publ i c Empl oyee {pr ot ect ed:Empl oyee *supervi sed[ 10] ;i nt number Of Peopl eManaged;publ i c:Manager ( I d, n) ;f l oat get Sal ar y( ) ;voi d pr i nt Super vi sedEmpl oyeeI d( ) ;
}
Jan-Feb 2016 93
Order of Constructor Calls
8/19/2019 SE - Lecture 03-30 [OOP in C++]
94/217
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 anappropriate constructor of the base class
Therefore, the constructor of the base class isexecuted first and then the constructor of thederived class is executed.
Jan-Feb 2016 94
8/19/2019 SE - Lecture 03-30 [OOP in C++]
95/217
Order of Destructor Calls
8/19/2019 SE - Lecture 03-30 [OOP in C++]
96/217
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 callsthe destructor of the base class
Therefore, the destructor of the base
class is executed first and then thedestructor of the derived class isexecuted.
Jan-Feb 2016 96
Casting
8/19/2019 SE - Lecture 03-30 [OOP in C++]
97/217
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 objectcan be seen through the base pointer.
e-> printSupervisedEmployeeId(); //error
Jan-Feb 2016 97
Casting
8/19/2019 SE - Lecture 03-30 [OOP in C++]
98/217
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-Feb 2016 98
Static vs Dynamic Binding
8/19/2019 SE - Lecture 03-30 [OOP in C++]
99/217
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-Feb 2016 99
Static vs Dynamic Binding
8/19/2019 SE - Lecture 03-30 [OOP in C++]
100/217
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 tomean “getSalary” of the Manager class.
We need a dynamic binding of “e” so that the typeof “e” may be set at run time by pointer to thetype of the actual object
This is also called late binding
Jan-Feb 2016 100
Virtual Functions
8/19/2019 SE - Lecture 03-30 [OOP in C++]
101/217
Virtual Functions In C++, dynamic binding is made
possible only for pointer & referencedata types and for methods that aredeclared as virtual in the base class.
If a method is declared as virtual , itcan be overridden in the derived class.
If a method is not virtual and it is re-
defined in the derived class then thelatter definition hides the former one.
Jan-Feb 2016 101
Virtual Function: Example
8/19/2019 SE - Lecture 03-30 [OOP in C++]
102/217
Virtual Function: Examplecl ass X{ cl ass Y: publ i c X{
publ i c: publ i c:
i nt f ( ) { r et ur n 2; } i nt f ( ) { r et ur n 4; }
vi r t ual i nt g( ) { r et ur n 3; } i nt g( ) { r et ur n 6; }
}; };
mai n( ) {
Y a;
i nt i , j , k, m;
X *b = &a;
i = b- >f ( ) ; j = a. f ( ) ;
k = b- >g( ) ; m = a. g( ) ;pr i nt f ( “%d %d %d %d\ n”, i , j , k, m) ;
}
Jan-Feb 2016
Output will be 2 4 6 6
102
Redefining a Non-Virtual
Function
8/19/2019 SE - Lecture 03-30 [OOP in C++]
103/217
Function Simply do not do that.cl ass X( ) { cl ass Y : publ i c X {
pr ot ect ed: pr ot ect ed:voi d f ( ) ; voi d f ( ) ;
}; };
i nt mai n( ) {
Y y1;
Y *pY; X *pX;
pX = &y1;
pX- >f ( ) ; / / f as def i ned i n X wi l l be cal l ed
pY = &y1;pY- >f ( ) ; / / f as def i ned i n Y wi l l be cal l ed
}
Jan-Feb 2016 103
8/19/2019 SE - Lecture 03-30 [OOP in C++]
104/217
8/19/2019 SE - Lecture 03-30 [OOP in C++]
105/217
Virtual Destructor
8/19/2019 SE - Lecture 03-30 [OOP in C++]
106/217
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 storeit 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 declaredvirtual then the destructor of the Derived classwill not be automatically called in this example.
Jan-Feb 2016 106
Inheritance Example:
Polymorphic Array
8/19/2019 SE - Lecture 03-30 [OOP in C++]
107/217
Polymorphic Array Consider an abstract base class Shape which
contains a pure virtual function “CalculateArea”.
Suppose three classes Triangle, Rectangle andCircle 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 seedynamic binding in use.
Jan-Feb 2016 107
Polymorphic Array: Class
Definitions
8/19/2019 SE - Lecture 03-30 [OOP in C++]
108/217
Definitionsclass 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-Feb 2016 108
8/19/2019 SE - Lecture 03-30 [OOP in C++]
109/217
Inheritance: Benefits
8/19/2019 SE - Lecture 03-30 [OOP in C++]
110/217
Code Sharing/Reuse
Consistency of Interface Construction of Software Components
Rapid Prototyping
Information Hiding
Jan-Feb 2016 110
Inheritance: Cost
8/19/2019 SE - Lecture 03-30 [OOP in C++]
111/217
Execution Speed
Program Size Message Passing Overhead
Program Complexity
Jan-Feb 2016 111
Inheritance: Limitations
8/19/2019 SE - Lecture 03-30 [OOP in C++]
112/217
operator= cannot be inherited
Can be used to assign objects of the sametype only
Copy Constructor cannot be inherited
Static members are inherited in aderived class
Static members cannot be “virtual”
If you redefine a static member function, allother overloaded functions in the base classare hidden
Jan-Feb 2016 112
Inheritance Notes
8/19/2019 SE - Lecture 03-30 [OOP in C++]
113/217
Constructors cannot be virtual
Calling a virtual function from within aconstructor 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 isredefined in Derived.
Jan-Feb 2016 113
Default Parameter & Virtual
Function
8/19/2019 SE - Lecture 03-30 [OOP in C++]
114/217
Do not change the default parameter in aredefined 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-Feb 2016 114
Is an Ostrich a Bird
8/19/2019 SE - Lecture 03-30 [OOP in C++]
115/217
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 throwexceptions?
Jan-Feb 2016 115
Is a Circle an Ellipse?
8/19/2019 SE - Lecture 03-30 [OOP in C++]
116/217
Circle is a special type of ellipse.
Let Circle be derived from Ellipse.
Suppose that Ellipse has a methodsetSize(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-Feb 2016 116
Should a Stack inherit from a
List?
8/19/2019 SE - Lecture 03-30 [OOP in C++]
117/217
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-Feb 2016 117
8/19/2019 SE - Lecture 03-30 [OOP in C++]
118/217
Inheritance & Code Reuse
8/19/2019 SE - Lecture 03-30 [OOP in C++]
119/217
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-Feb 2016 119
private Inheritance If B is privately derived from A then private
8/19/2019 SE - Lecture 03-30 [OOP in C++]
120/217
If B is privately derived from A then private,protected and public members of A become
private members of B. However, privatemembers of A are not directly accessible to B.
Thus, even if C is publicly derived from B thenno member of A is accessible to C .
Functions which may access members of A in Bare
Methods of class B
Friend functions of class B.
Jan-Feb 2016 120
protected Inheritance If B i t t dl d i d f A th
8/19/2019 SE - Lecture 03-30 [OOP in C++]
121/217
If B is protectedly derived from A then,protected and public members of A become
protected members of B. However, privatemembers of A remain private in B and are notdirectly 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-Feb 2016 121
Private Inheritance: Implications public Inheritance models “is a”
8/19/2019 SE - Lecture 03-30 [OOP in C++]
122/217
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 Setcan be implemented in terms of a list.
Users of the class Set should not have an access to theList behavior even to create further derived classes
Jan-Feb 2016 122
8/19/2019 SE - Lecture 03-30 [OOP in C++]
123/217
TYPE CASTING
Object-Oriented Programming in C++
Jan-Feb 2016 123
Type Casting Why casting?
8/19/2019 SE - Lecture 03-30 [OOP in C++]
124/217
Why casting?
Casts are used to convert the type of an object,
expression, function argument, or return value tothat of another type.
(Silent) Implicit conversions.
The standard C++ conversions and user-defined
conversions
Explicit conversions.
type is needed for an expression that cannot beobtained through an implicit conversion
more than one standard conversion creates anambiguous situation
Jan-Feb 2016 124
Type CastingTo perform a type cast the compiler
8/19/2019 SE - Lecture 03-30 [OOP in C++]
125/217
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;}
Jan-Feb 2016 125
Automatic (Implicit) Conversion Automatic conversions from one type to
8/19/2019 SE - Lecture 03-30 [OOP in C++]
126/217
Automatic conversions from one type toother may be extremely convenient.
Automatic conversions (eitherconversion operators or single argumentnon-explicit constructors) are unsafe aswell.
can interfere with overload resolutions.
can silently let wrong code compile cleanly.
String s1, s2, s3;
s3 = s2 – s1; // Though “-” is not overloaded in StringJan-Feb 2016 126
8/19/2019 SE - Lecture 03-30 [OOP in C++]
127/217
Casting to User Defined Type The assignment statement is
8/19/2019 SE - Lecture 03-30 [OOP in C++]
128/217
The assignment statement is
converted to the following s1 = String(“example”);
Lots of temporary objects are created.
Even the following statement iscorrect:
s1 = s2 + “abc” + “def”;
Jan-Feb 2016 128
Ambiguities: Example Overuse of such f1 (const String & )
8/19/2019 SE - Lecture 03-30 [OOP in C++]
129/217
Overuse of suchcasting may lead to
ambiguities asillustrated in thefollowing example
/* ambig.cpp */
#include “string.h”
class example {
public:
example(const char *) { } ;
} ;
void
{
}
void
f1 (const example & )
{
}
int
main ( )
{ // f1 (“hello, world”) ; is ambiguous
f1 ((String) “hello world” );
f1 ((example) “hello world” );
// or provide void f1 (const char *)
return 0;
}
Jan-Feb 2016 129
Ambiguity: Exampleclass B;
l A { Which one to use for
8/19/2019 SE - Lecture 03-30 [OOP in C++]
130/217
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 forcasting?
Constructor in A OR Cast Operator in B
Jan-Feb 2016 130
8/19/2019 SE - Lecture 03-30 [OOP in C++]
131/217
Example of user defined castconst int max_string_length = 128;
class String {
void operator-(const String &, constString &);
8/19/2019 SE - Lecture 03-30 [OOP in C++]
132/217
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]
};
g );
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 onlyto const char *
// strcpy (filename, “zbc”);
String name = “ZaphodBeeblebrox”;
name – “Beeblebrox”; // is now
ambiguous.return 0 ;
}
Jan-Feb 2016 132
Avoiding Ambiguitiesconst int max_string_length = 128;
class String {
void operator-(const String &, constString &);
8/19/2019 SE - Lecture 03-30 [OOP in C++]
133/217
g {
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];};
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 = “ZaphodBeeblebrox”;
name – “Beeblebrox”; // is no longerambiguous
return 0;
}
Jan-Feb 2016 133
Casting Pointers & References Casting a value:
8/19/2019 SE - Lecture 03-30 [OOP in C++]
134/217
float f_var = 3.14;
cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
135/217
There are four cast operators in C++
const_cast
static_cast
reinterpret_cast
dynamic_cast
Only dynamic_cast is not equivalentto a C-style cast
Jan-Feb 2016 135
Prefer C++ casts to C-style
casts Type conversions of any kind (either explicit
i t i li it b il ) ft l d t
8/19/2019 SE - Lecture 03-30 [OOP in C++]
136/217
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 semanticsthat compilers may use.
More narrowly specified purpose for eachspecified cast; compilers can diagnose usererrors.
Some casts are performed safely at run-time.
Jan-Feb 2016 136
const_cast operator Syntax:
8/19/2019 SE - Lecture 03-30 [OOP in C++]
137/217
const_cast < type-id > ( expression )
The const_cast operator can be used to remove theconst, volatile attribute(s) from a class.
A pointer to any object type can be explicitly convertedto a type that is identical except for the const, volatile
qualifiers. Applying on pointers and references, theresult will refer to the original object.
The const_cast operator cannot be used to directlyoverride a constant variable's constant status.
Jan-Feb 2016 137
const_cast operator: ExampleExample
#include int main() {
CCTest X;
8/19/2019 SE - Lecture 03-30 [OOP in C++]
138/217
class CCTest {
public:
void setNumber( int );
void printNumber() const;
private:
int number;
};
void CCTest::setNumber( int num ){ number = num; }
void CCTest::printNumber() const {
cout number--;cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
139/217
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 anon-const parameter and it is knownthat the function does not modify that
parameter then casting away const-nessis both useful and safe.
Jan-Feb 2016 139
Guidelines for const const is a powerful tool for writing safer code;
it h ibl b t
8/19/2019 SE - Lecture 03-30 [OOP in C++]
140/217
use it as much as possible but no more.
Do not use const pass-by-value parameters infunction declarations. This is not useful andmisleading at best.
When returning a user defined type, preferreturning a const value.
Do not return handles to internal data from aconst member function.
Jan-Feb 2016 140
static_cast operator Syntax:
8/19/2019 SE - Lecture 03-30 [OOP in C++]
141/217
static_cast < type-id > ( expression )
The static_cast operator converts expression tothe type of type-id based solely on the typespresent in the expression.
static_cast has basically same power, meaningand restrictions as C-style cast. It cannot beused to convert a struct into an int or a double
into a pointer.
Jan-Feb 2016 141
8/19/2019 SE - Lecture 03-30 [OOP in C++]
142/217
Example:
class B { ... };
static_cast: Example The static_cast operator
can be used forti h
8/19/2019 SE - Lecture 03-30 [OOP in C++]
143/217
{ };
class D:public B { ... };
void f(B* pb, D* pd){D* pd2 =
static_cast(pb); // not safe, pb may point to just B
B* pb2 = static_cast(pd); // safe conversion
...
}.
operations such as
converting a base classpointer to a derived classpointer . Suchconversions are notalways safe since no run-
time type check is madeto ensure the safety ofthe conversion.For suchconversions dynamic_castshould be used.
Jan-Feb 2016 143
8/19/2019 SE - Lecture 03-30 [OOP in C++]
144/217
reinterpret_cast operator Syntax:
8/19/2019 SE - Lecture 03-30 [OOP in C++]
145/217
reinterpret_cast < type-id > ( expression )
The reinterpret_cast operator allows anypointer to be converted into any other pointertype. 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*, orOne_class* to Unrelated_class*, which areinherently unsafe.
Jan-Feb 2016 145
reinterpret_cast operator The result of a reinterpret_cast cannot safely be used for
anything other than being cast back to its original type.
8/19/2019 SE - Lecture 03-30 [OOP in C++]
146/217
y g g g ypOther uses are, at best, non-portable.
The reinterpret_cast operator cannot cast away theconst, volatile attributes.
One practical use of reinterpret_cast is in a hash
function, which maps a value to an index in such a waythat two distinct values rarely end up with the sameindex.
Reinterpret_cast should rarely be used in a C++
program
Jan-Feb 2016 146
reinterpret_cast: ExampleExample
#include
unsigned short Hash( void *p ){
The reinterpret_castallows the pointer to bet t d i t l
8/19/2019 SE - Lecture 03-30 [OOP in C++]
147/217
unsigned short Hash( void *p ){
// Returns a hash code based on anaddress
unsigned int val =reinterpret_cast( p);
return ( unsigned short )( val ^ (val
>> 16));}
int main(){
int a[20];
for ( int i = 0; i < 20; i++ )
cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
148/217
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;
_
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-Feb 2016 148
Avoid Unnecessary Cast Look at the cast and commentclass SpecialWindow: public Window { // derived class
8/19/2019 SE - Lecture 03-30 [OOP in C++]
149/217
class SpecialWindow: public Window { // derived class
public:virtual void onResize() { // derived onResize impl;
static_cast(*this).onResize(); // cast *this to Window,
// then call its onResize;
// this doesn’t work!... // do SpecialWindow-
} // specific stuff
...
};
Jan-Feb 2016 149
type_info class The type_info class describes type information
generated within the program by the compiler. Theti d fi iti f thi l i i l t ti
8/19/2019 SE - Lecture 03-30 [OOP in C++]
150/217
entire definition of this class is implementation
dependent but the following features of this class isstandardized.
Objects of this class effectively store a pointer to aname for the type. The type_info class also stores an
encoded value suitable for comparing two types forequality or collating order.
The operators “==“ and “!=“ are overloaded and canbe used to compare for equality and inequality withother type_info objects, respectively.
Jan-Feb 2016 150
type_info class Features of type_info class (contd):
The “name” member function returns a const char*
8/19/2019 SE - Lecture 03-30 [OOP in C++]
151/217
to a null-terminated string representing the human-readable name of the type. The memory pointed to iscached and should never be directly deallocated.
Type information is generated for polymorphicclasses only if the /GR (Enable Run-Time Type
Information) compiler option is specified.
Jan-Feb 2016 151
8/19/2019 SE - Lecture 03-30 [OOP in C++]
152/217
typeid operator When the operand of typeid is of a non-
polymorphic class type, the result is the type of
8/19/2019 SE - Lecture 03-30 [OOP in C++]
153/217
the operand not the type of the underlyingobject.
type-id may be used with operands of built-intypes.
Jan-Feb 2016 153
The expression usuallypoints to a polymorphictype (a class with virtual
typeid:Exampleint main(){
Derived* pd = new Derived;
Base* pb = pd;
t t id( b ) () dl
8/19/2019 SE - Lecture 03-30 [OOP in C++]
154/217
yp (functions).
The pointer must be de-referenced so that theobject it points to is used.Without de-referencing thepointer, the result will be
the type_info for thepointer, not pointee
Example#include
#include
class Base {public: virtual void vvfunc() {} }
class Derived : public Base {};
cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
155/217
id> (expression)
The expressiondynamic_cast( expression)
converts theoperand expressionto an object of typetype-id.
It is used for down-casting.
class D : public C { ... };
void f(D* pd){C* pc = dynamic_cast(pd);
// ok: C is a direct base class, pc points toC subobject of pd
B* pb = dynamic_cast(pd); // ok: B is an indirect base class , pbpoints to B subobject of pd
...}
Jan-Feb 2016 155
8/19/2019 SE - Lecture 03-30 [OOP in C++]
156/217
dynamic_cast If dynamic_cast to a pointer type fails, the result of the
dynamic_cast is null; if dynamic_cast to a reference typefails, an exception is thrown.
8/19/2019 SE - Lecture 03-30 [OOP in C++]
157/217
, p
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_castoperator can be used to cast from a derived class pointerto a base class pointer, cast a derived class pointer toanother derived (sibling) class pointer, or cast a baseclass pointer to a derived class pointer. Each of theseconversions may also be applied to references.
Jan-Feb 2016 157
dynamic_cast dynamic_cast operator cannot be used for built-in types.
All of the derived-to-base conversions are performedusing the static (compile-time) type information. These
8/19/2019 SE - Lecture 03-30 [OOP in C++]
158/217
using the static (compile time) type information. These
conversions may, therefore, be performed on both non-polymorphic and polymorphic types. These conversionswill produce the same result if they are converted using astatic_cast. However, even these results may be wrong inthe presence of multiple inheritance.
dynamic_cast is strongly recommended to be applied onpolymorphic types.
Jan-Feb 2016 158
Cost of dynamic_cast The pointer to the type_info object of a class is
stored in the vtbl array of the class.
8/19/2019 SE - Lecture 03-30 [OOP in C++]
159/217
Thus, the space cost for RTTI is an additionalentry in each class vtbl plus the cost of storagefor the type_info object for each class.
Size of the objects do not increase for RTTIoperations.
Cost of RTTI at run time is similar to the costof calling a virtual function; cost of calling a
virtual function is the same as the cost ofcalling a function through a function pointer.
Jan-Feb 2016 159
8/19/2019 SE - Lecture 03-30 [OOP in C++]
160/217
EXCEPTIONSObject Oriented Programming in C++
Jan-Feb 2016 160
Topics Basic Concept of Exceptions
try-catch block in C++
8/19/2019 SE - Lecture 03-30 [OOP in C++]
161/217
try catch block in C++
Semantics of throw
Jan-Feb 2016 161
Error Handling in C++ Error Condition Handling - C Style
via return value
8/19/2019 SE - Lecture 03-30 [OOP in C++]
162/217
return statement is dedicated for passingerror conditions
by output parameter
normal and abnormal control flowtend to mix
Reusing code for error handling isdifficult.
Jan-Feb 2016 162
Error Handling in C++ Error Condition Handling - C++
Style
8/19/2019 SE - Lecture 03-30 [OOP in C++]
163/217
On error condition an exception objectis created and thrown.
A function catches exception objects
generated from the function it calls ina distinct control flow.
Similar Exception objects can enjoy
benefits of inheritance.
Jan-Feb 2016 163
C-Style Error Handling A Calculator need to
handle divide by zero
i ntCal cul at or : : di vi de ( i nt i ){
i f ( i == 0)
8/19/2019 SE - Lecture 03-30 [OOP in C++]
164/217
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-Feb 2016 164
i f ( i 0){
/ / what do we do?}el se{
val ue / = i ;}r et ur n val ue;
}
8/19/2019 SE - Lecture 03-30 [OOP in C++]
165/217
Exception Object and throw Exception object is just another object having
members (attributes and methods) suitable tomodel the state and behavior of an object
8/19/2019 SE - Lecture 03-30 [OOP in C++]
166/217
jrepresenting an error condition.
Whenever an error condition is detected, asuitable Exception object is thrown. Semantics
of throw is as follows. Creation of an object (function of new)
passing control from this function to the callerfunction (similar to return)
Unlike return, throw initiates unwinding of the callstack till the exception is handled.
Jan-Feb 2016 166
Example of Exception Handlingin C++class DivideByZero {
private:
int dividend;
public:
int main (int argc, char **argv) {
int i = 0;
Calculator c;
try {
8/19/2019 SE - Lecture 03-30 [OOP in C++]
167/217
print() {
cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
168/217
Jan-Feb 2016 168
by zer o”
8/19/2019 SE - Lecture 03-30 [OOP in C++]
169/217
More on try and catch
Whenever a function is called in a try block,the catch blocks to be examined after the try
8/19/2019 SE - Lecture 03-30 [OOP in C++]
170/217
block are known as the extended prototype ofa function includes the throw clauses.
catch blocks after a try block are examined inorder 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-Feb 2016 170
8/19/2019 SE - Lecture 03-30 [OOP in C++]
171/217
8/19/2019 SE - Lecture 03-30 [OOP in C++]
172/217
Stack Frame
g++ -s gives assembler output thatcan be used to deduce exact structurefor a given platform
I l th ll t t i
automatic variables
8/19/2019 SE - Lecture 03-30 [OOP in C++]
173/217
In general, the overall structure iscommon
A chunk of memory representing afunction call
Allocated on program call stack atruntime. Contains:
The frame pointer
The return address for the call (i.e., whereit was called from)
Parameters passed to the function Automatic (stack) variables for the function
previous frame pointer
return address
parameters
Jan-Feb 2016 173
Illustrating the Call Stack
int main (int argc, char **argv) {
int i = 0;
Calculator c;
try {
Stack frame for function main Allocated on program call stack
With stack variables i and c
With parameters argc and argv
Note that parameters are
8/19/2019 SE - Lecture 03-30 [OOP in C++]
174/217
c.divide (0);
cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
175/217
c.divide (0);
cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
176/217
Illustrating the Call Stack, cont.
Calculator::Calculator ()
: value_ (0)
{}
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
8/19/2019 SE - Lecture 03-30 [OOP in C++]
177/217
void
Calculator::divide (int i) throw (int)
{
if (i == 0) {
throw i;
} else {
value_ /= i;
}
cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
178/217
void
Calculator::divide (int i) throw(int) {
if (i == 0) {throw i;
} else {
value_ /= i;
}
cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
179/217
try {
c.divide (0);
cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
180/217
Throw integer i
main
void Calculator::
Calculator (int )
argc argv
i c value_
this i
void
Calculator::divide (int i) throw (int)
{
if (i == 0) {
throw i;
} else {
value_ /= i;
}
cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
181/217
void
Calculator::divide (int i) throw(int)
{
if (i == 0) {
throw i;
} else {
value_ /= i;
}
cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
182/217
c.divide (0);
cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
183/217
// ...
}
catch (Base &b) {
// ...
}
catch (...) // catch all...
{
// ...
}
p yinheritance-relatedexception classes
Hint: put catch blocks forderived exception classes
before catch blocks fortheir respective baseclasses
More specific catch beforemore general catch
catch (…) catches anytype
Jan-Feb 2016 183
A Few More on catchtry
{
// can throw an exception
}
catch (MyClass &e){
Notice catch-by-referencefor user defined types More efficient
Only a reference propagates
Rather than entire object
8/19/2019 SE - Lecture 03-30 [OOP in C++]
184/217
{
// ...
throw; // rethrows e
}
catch (int)
{ // ...
}
catch (...) // catch all...
{
// ...
}
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-Feb 2016 184
8/19/2019 SE - Lecture 03-30 [OOP in C++]
185/217
TEMPLATESObject-Oriented Programming in C++
Jan-Feb 2016 185
What is a Template?
Templates are specifications of acollection of functions or classes whichare parameterized by types.
Examples:
8/19/2019 SE - Lecture 03-30 [OOP in C++]
186/217
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-Feb 2016 186
8/19/2019 SE - Lecture 03-30 [OOP in C++]
187/217
Example
#i ncl ude #i ncl ude usi ng namespace st d;
t empl at e i nl i ne T const & Max ( T const & a, T const & b){ b ? b }
8/19/2019 SE - Lecture 03-30 [OOP in C++]
188/217
Jan-Feb 2016 188
{ r et ur n a < b ? b: a; }
i nt mai n ( ) {i nt i = 39; i nt j = 20;cout
8/19/2019 SE - Lecture 03-30 [OOP in C++]
189/217
Jan-Feb 2016 189
t empl at e cl ass St ack {
pr i vat e: vect or el ems; / / el ement s
publ i c:voi d push( T const &) ; / / push el ementvoi d pop( ) ; / / pop el ement T t op( ) const ; / / r et ur n t op el ementbool empt y( ) const { / / r et ur n t r ue i f empt y.
r et ur n el ems. empt y( ) ; }};
Parameterized Functions
A function template describes how a function should be built
supplies the definition of the function using somearbitrary types, (as place holders),
8/19/2019 SE - Lecture 03-30 [OOP in C++]
190/217
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-Feb 2016 190
Template Non-type Parameter
It is an ordinary parameter
template T min (T
(&x[size]));
8/19/2019 SE - Lecture 03-30 [OOP in C++]
191/217
When min is called, size is replaced witha constant value known at compile time
The actual value for a non-typeparameter must be a constantexpression.
Jan-Feb 2016 191
typename
The key words class and typename havealmost the same meaning in a templateparameter
typename is also used to tell the compiler that
8/19/2019 SE - Lecture 03-30 [OOP in C++]
192/217
yp pan expression is a type expression
template f (T x) {T::name * p; // Is this a pointer declaration or multiplication?
}
template f (T x) {
typename T::name * p; // Is this a pointer declaration or
multiplication?
}
Jan-Feb 2016 192
Template Argument Deduction
Each item in the template parameter list is atemplate argument
When a template function is invoked, thevalues of the template arguments aredetermined by seeing the types of the function
8/19/2019 SE - Lecture 03-30 [OOP in C++]
193/217
determined by seeing the types of the functionarguments
template Type min( T(&x[size]));
int pval[9]; min(pval); //Error!!
Jan-Feb 2016 193
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
8/19/2019 SE - Lecture 03-30 [OOP in C++]
194/217
Conversion to a base class instantiation from a classtemplate
If the same template parameter are found for
more than one function argument, templateargument deduction from each functionargument must be the same
Jan-Feb 2016 194
Explicit Template Arguments
It is possible to override template argumentdeduction mechanism and explicitly specifythe template arguments to be used.
template T min(T x, T y); unsigned int ui; min (ui 1024); //Error!!
8/19/2019 SE - Lecture 03-30 [OOP in C++]
195/217
unsigned int ui; min (ui, 1024); //Error!!
min(ui, 1024); // OK
Specifying return type generically is often a
problem. template ??? 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(i, ‘a’);
Jan-Feb 2016 195
Template Explicit Specialization
Some times, a template may not besuitable for all types.
The following template is not good forchar *
8/19/2019 SE - Lecture 03-30 [OOP in C++]
196/217
char *template T min(T x, T y)
{ return (x < y) ? x : y); } Define the function explicitly for char *
template char * min (char *x, char *y)
{ return ((strcmp(x, y) < 0) ? x : y); }
Jan-Feb 2016 196
A List Template Classtemplate
class List {
public :
List ();
virtual ~List ();
int put (const T &val);T *unput ();
T *get ();
template int List:: 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)
8/19/2019 SE - Lecture 03-30 [OOP in C++]
197/217
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;
};
if (end_ptr)
end_ptr->next_item = tmp_ptr;
else
beg_ptr = tmp_ptr;
end_ptr = tmp_ptr;how_many++;
return 1;
}
else