Oop
Oop
Uttam K. Roy
Dept. of IT, JU u_roy@it.jusl.ac.in
Books
B. Stroustrup, The C++ Programming Language, Addison Wesley publication E. Balagurusamy, Object Oriented Programming with C++, Tata McGrawHill publication Yashwant Kanetkar, Let Us C++, BPB publication Lipman, C++ Primer
U.K.R., 2008
OOP
What Is C++?
Compatible extension of C Support Object Oriented Programming Support for Data Abstraction
U.K.R., 2008
OOP
Background
C++ designed by Bjarne Stroustrup (AT&T Bell Labs) Originally only meant as a pre-processor to improve on some of the inadequacies of C First commercial release 1985 Even today many consider C++ is not an object oriented language but rather an object oriented compiler-linker (subtle difference we'll learn about later).
U.K.R., 2008 OOP 4
C++
Flexible (you can make mistakes in a wide variety of ways!) Efficient (you can make those mistakes very quickly!) Available (everyone can make mistakes together!) Portable (you can transport those mistakes to other systems!) Very untidy syntax Lack of type safety memory management not automatic
OOP 6
Weaknesses
U.K.R., 2008
Philosophy of C++
Keep the strengths and repair the weaknesses
Efficiency is maintained Compatibility is maintained with C Operate in all environments C can Improved typing Abstraction and Data encapsulation vastly improved Inheritance and Polymorphism introduced
U.K.R., 2008
OOP
U.K.R., 2008
OOP
OOP Language?
An Object Oriented Programming Language is one which fully supports the fundamental concepts of Object Oriented approach, namely:
Definition of class and declaration of objects Enforcement of information hiding The ability to define an inheritance hierarchy of classes The ability to code polymorphic methods Invocation of an objects method by message passing
OOP 9
U.K.R., 2008
SmallTalk (The first OOPL) Eiffel (powerful language that supports selective inheritance) C++ (does not enforce information hiding) Object Pascal (does not support information hiding and does not support multiple inheritance) Object COBOL (does not enforce information hiding) Visual Basic, Paradox, ToolBook etc.
U.K.R., 2008
OOP
10
inline template
U.K.R., 2008
OOP
12
Flexible declaration
In C, when you write a function, all the declaration of local variables must appear at the top of the function or at the beginning of a block
#include <iostream.h> main( ) { for(int f = 0; f < 100; f++) { float c = (f 32)*5/9.0; cout << c << << f << \n; } }
U.K.R., 2008 OOP 14
Type Names
In C, a common style of variable declaration is
struct A { int x; }; typedef struct A A; A a;
In C++, classes, structs, unions, and enum names are automatically type names, so you can say:
U.K.R., 2008 OOP
Enumeration names
In C++, enumeration names can have values assigned to them, whereas in c they can not
//C style enum Color {Red, Green, Blue}; //C++ style enum Color {Red=2, Green=4, Blue=6}; Color background=Blue; enum Armstrong {first=153, second=370, third=371}; Armstrong one=first; Armstrong two=second;
U.K.R., 2008 OOP 16
Type Casting
In C++, type casting can be done in two different ways:
Function prototype and default values In C, functions may have a prototype defined before implementation. In C++ it is compulsory In addition, arguments may have default values specified in the prototype which can be used when function is called without any argument
int square(float); void setBackground(Color c=Red);
U.K.R., 2008
OOP
18
Accessing variables
Global variable can be accessed using scope resolution operator while a local variable with the same name is already declared
int x=2; int main() { int x=5; cout << x; //local x cout << ::x; //global x }
U.K.R., 2008
OOP
19
Constant variable
Value once set can never be changed Example: main( ) {
const float PI = 22/7.0; int radius = 10; float area = PI*radius*radius; PI=6.2; //error }
Benefits:
U.K.R., 2008
Using #define
//incorrect, y = 4-2*4-2 = -6
Using const
//correct, y = 2*2 = 4
OOP
21
int * const r = &x; //pointer r is const, but variable pointed by r, is not *r = 10; //ok r = &y; //error const int * const s = &x; //pointer as well as variable pointed by s are const *s = 12; //error s = &y; //error
U.K.R., 2008 OOP 23
Application
void Strcpy(char * const dst, const char * const src) { char ch; src = &ch; //error src[0] = a; //error dst = &ch; //error }
U.K.R., 2008
OOP
24
Reference Variable
Creates an alternate name or alias for the variable Can be used to read or modify the original data stored in that variable Syntax of reference variable declaration:
Standard or user defined data type: char, short, int, float, etc. Reference operator C++ alias variable C++ original variable
ReferenceVariable
U.K.R., 2008 OOP 25
Reference Variable
int count = 1; // declare integer variable count int &ref = count; // create ref as an alias for count count ++; // increment count normally ++ref; // increment count (using its alias)
1000
count
3 2 1
ref
int x = 2,y = 6; int * const ref = &x; //ok, x=4 *ref = 4; ref = &y; //error
26
Restrictions
You cannot reference of a reference variable You cannot create array of references You can not create pointer to a reference
U.K.R., 2008
OOP
27
//declaration syntax error //ok, y is const and r is a read only alias //error //error
OOP 28
Usage of References
Call by value:
main( ) { int x=4, y=5; //actual args change(x, y); }
x 4
y 5
a 5 4
temp
b 4 5
OOP
29
Usage of References
Call by address:
main( ) { int x=4, y=5; //actual args change(&x, &y); }
1000
x 5 4
1002
y 4 5
a
void change(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; }
U.K.R., 2008 OOP
b
1006 1002
1004
1000 1008
temp
30
Usage of References
Call by reference:
main( ) { int x=4, y=5; //actual args change(x, y); }
x 5 4 a
y 4 5 b
temp
OOP
31
Usage of References
Avoid unnecessary copying
float deteminant(Matrix &m) { /*find determinant of matrix m here*/ }
Return by References
int a = 4;
Function call
f() = a;
Result
x=4
U.K.R., 2008
OOP
33
Inline Functions
Eliminates the function-call overhead (caused by jumping in and out of functions having few statements) involved in the conventional functioning approach. Keyword inline before function Asks the compiler to copy code into program instead of making function call Compiler can ignore inline Good for small, often-used functions
U.K.R., 2008 OOP 34
Inline Functions
Syntax of inline function definition:
Specified using the same syntax as any other function except that they include the inline keyword in the function declaration.
Keyword, function qualifier
U.K.R., 2008
OOP
35
Inline Functions
Example
inline int sqr(int num) { return num * num; }
void main( ) { compiler // a = sqr(5); b = sqr(n); // } void main( ) { // a = 5*5; b = n*n; // }
//impossible to substitute
36
U.K.R., 2008
OOP
37
Expressions passed as arguments to inline functions are evaluated once. In some cases, expressions passed as arguments to macros are evaluated more than once.
U.K.R., 2008
OOP
38
inline float square(float j) { return (j * j); } void main( ) { int p=3,q=3,r,s; r=SQUARE(++p); s=square(++q); cout<<r = << r << s = <<s; }
r =25 s =16
Macro SQUARE( ) is expanded as r = ++p * ++p In macro expansion p is incremented twice. inline function square( ) var q is incremented only once and is assigned to j then j * j is returned.
OOP 39
U.K.R., 2008
Function Overloading
Having more than one function with the same name differing in number, type and order of arguments It is a kind of Compile time Polymorphism
int abs(int); float abs(float); double abs(double); void print(int); void print(float); void print(int *, int); void print(Matrix m); void print(Student); //print an integer //print a float //print an array //print a matrix //print student data
U.K.R., 2008
OOP
40
Function Overloading
Issues in Function Overloading
Functions differing in their return types only cannot be overloaded.
int pop(Stack &); float pop(Stack &); char pop(Stack &);
The compiler attempts to find an accurate function definition that matches in types and number of arguments and invokes the function. If no accurate match found, compiler tries out implicit conversions. e.g., char is converted to int, float to double etc. If no accurate match found
may lead to ambiguity as internal type
Ambiguity
conversions may take place. Consider: sum(int,int) and sum(float, float) The compiler will not be able to identify the function to be called
sum(1.1, 2.2);
U.K.R., 2008
Default Values
void drawCircle(int x, int y, int radius); drawCircle(0,0,100); drawCircle(0,0,100, GREEN); //draw with WHITE color //error, 3 arguments needed
void drawCircle(int x, int y, int radius, int color=WHITE); drawCircle(0,0,100); drawCircle(0,0,100, GREEN); //color=WHITE //color=GREEN
Function arguments assume default values, when their values are neglected or insufficient number of values are furnished during function calls. Can be constants, global variables, or function calls
U.K.R., 2008 OOP 42
Default Values
U.K.R., 2008
OOP
43
Default Values
Basic rules: When a default is provided, all parameters must be given defaults.
remaining
Default values must be of the correct type. Defaults can be placed on the function prototype or the function definition.
U.K.R., 2008
OOP
44
Data variable
Object A Object C
U.K.R., 2008
OOP
46
U.K.R., 2008
OOP
47
U.K.R., 2008
OOP
48
U.K.R., 2008
OOP
49
Terminology
Class - A software module that provides both procedural and data abstraction. It describes a set of similar objects, called its instances
Attribute - A simple data item present in all the instances of a class Data type - A name or label for a set of values and some operations which one can perform on that set of values. Association - A relationship between two classes that represents the existence of a set of links between objects of the two classes
window origin size open() close() move() display() Window Class
U.K.R., 2008
OOP
50
Classes
Polygon Abstract into vertices border area fillColor draw( ) erase( ) move( ) Class
Attributes
Polygon Objects
Operations
U.K.R., 2008
OOP
51
Classes
Attributes
Customer name address phone birthDate attributes Wall height::Float width::Float Thickness::Float isMovable::Boolean=false attributes
Customer Atrributes
Classes
Operations
Rectangle area() grow() move isEmpty() Operations TeperatureSensor
operations
operations
ATM
validate(crd: ATMCard, pin: Integer) withdraw(amount: Float) deposit(amount: Float) balance(): Float Oerations
U.K.R., 2008
OOP
53
Encapsulation
Bundling of the data and methods together
Transaction
Ensuring that users of an object cannot change the internal state of the object in unexpected ways; only the object's own internal methods are (generally) allowed to access its state. Each object exposes an interface that specifies how other objects may interact with it. Other objects will rely exclusively on the object's external interface to interact with it.
U.K.R., 2008
OOP
54
Inheritance
Ability to extend/subclass the behavior of existing class without changing the original class New class is called derived class/sub class Old class is called super class/base class Sub class inherits all the behavior of its super class New fields and methods can be added in the sub class
U.K.R., 2008
OOP
55
Inheritance
Shape origin move() resize() display() base/parent class Party
generalization
Customer
Supplier
Employer
derived/child class
OOP
56
Polymorphism
Many(poly-) forms(-morph) Function overloading Operator overloading Inheritance Virtual function
U.K.R., 2008
OOP
57
Objects
U.K.R., 2008
OOP
58
Objects
U.K.R., 2008
OOP
59
Access Control
A member of a class can be private, public. (In inheritance, we use another access specify namely protected. So, a member of a class can be private, protected, or public.) If it is public, its name can be used by any function. If a member of a class is private, its name can be used only by member functions and friends of the class in which it is declared. If it is protected, its name can be used only by member functions and friends of the class in which it is declared and by member functions and friends of classes derived from this class.
U.K.R., 2008 OOP 60
Access Control
struct Complex { private : double real, img; public : void set(double r, double i) { real = r; img = i; } Complex add(Complex c) { Complex temp; temp.set(real+c.real, img+c.img); //real and img are //accessible from member function } /**/ }; void main( ) { Complex c1, c2; c1.real=1.5; c1.img=3.4; c1.set(1.5, 3.4); c2.set(5.6, 8.8); double d = c1.add(c2); }
U.K.R., 2008 OOP 61
//error, real and img are private; //not accessible from outside //ok, access through public member function //ok, access through public member function
Member function defined insideinlined by default Member function defined outsidenot inlined Member function defined outside inlined explicitly
62
this pointer
class Point { public: int x, y; void setx(int xx) {x=xx;} /**/ }; void main( ) { Point p1, p2; p1.setx(2); p2.setx(6); } x, y p1 x, y p2
64
Solution is constructor
class Point { public: int x, y;
Constructor declared Constructor defined Object created and initialized by constructor Inside Point( ) Inside main( ) x= 2 y= 4
Point( );
};
Point::Point(void)
{ cout<<" Inside Point( )\n"; x=2;y=4; // if not initialized garbage } void main( ) { Point p; //Point p = Point(); cout<<"Inside main( )\n"; cout<<"x= " << p.x<<"y= "<<p.y; }
U.K.R., 2008 OOP
Object p x= 2 y= 4
65
Constructors contd.,
Constructors are special member functions with the same name as the class. A constructor on each object is called when it is created They are commonly used to initialize the member variables. Constructors do not return values. They have no return type specified
U.K.R., 2008
OOP
66
Constructors contd.,
A constructor is called whenever an object is defined or dynamically allocated using the new operator If no constructor is explicitly written then a default is created (not in the case of const and reference data members). The purpose of a copy constructor is to initialize a new object of a given class by copying an existing object of that class.
U.K.R., 2008
OOP
67
U.K.R., 2008
OOP
68
Parameterized Constructor
Object p1 Object p2
x= 10 y= 20 x= 30 y= 40
69
Overloading Constructors
Overloading Constructors - Multiple constructors declared in a class All constructors have different number of arguments Depending on the number of arguments, compiler executes corresponding constructor
Point( ) {x=10;y=20;}; Point(int i, int j) {x=i;y=j;};
No arguments: Point p;
U.K.R., 2008
OOP
71
Copy Constructors
Constructors can accept arguments of any data type including user defined data types and an object of its own class C++ calls a copy constructor to make a copy of an object. If there is no copy constructor defined for the class, C++ uses the default copy constructor which copies each field, ie, makes a shallow copy. Point p1(10); //Object created and initialized Point p2(p1); //Copy constructor Point p3=p1; //Copy constructor Point p4; p4=p1; //Member wise copy
U.K.R., 2008 OOP 72
Objects
o1 x=10
o2 x=10
OOP
o3 x=10
o4 x=10
73
U.K.R., 2008
Solution
class Stack { public : Stack(const Stack &s) { top=s.top; int *temp=a; a=new int[size=s.size]; for(int i=0;i<size;i++) a[i]=s.a[i]; delete(temp) } }; size s1 a
3 6 9 4
top size a
After s2=s1
74
top
Solution
class String { String(const String &str) { length = str.length; buf = new char[length+1]; strcpy(buf, str.buf); } };
C + + 4 3 6 9 \0
After s2=s1
75
U.K.R., 2008
OOP
Destructors
When an object goes out of scope then it is automatically destructed. It performs clean up of the object ( using delete in the case of allocating memory inside the object using new ) Destructors have no arguments and thus cannot be overloaded
U.K.R., 2008
OOP
76
Destructors contd.,
Declaration Same name as class Preceded with tilde (~)
~Point( ) { }
U.K.R., 2008
OOP
77
Static Members
class Point { int x, y; /**/ }; Point p1, p2;
x, y p1 x, y p2
U.K.R., 2008
OOP
78
Static Members
Static Data Members:
Static members are members that are single shared member common to all the objects created for a particular class. Memory allocation is done only once and not every time an object is created.
Object A
Object B
Static variable
Object C
U.K.R., 2008 OOP 79
U.K.R., 2008
OOP
80
Object myAccount
U.K.R., 2008
currentBal=0
OOP
currentBal=1
81
Object aCar
U.K.R., 2008
serialNo=10
OOP
serialNo=11
82
class Car { public : static int nextSerial; static void reset() { nextSerial = 0; } };
U.K.R., 2008
OOP
83
Constant Functions
Declaring a member function with the const keyword specifies that the function is a "read-only" function that does not modify the object for which it is called. If a const function attempt to change the data, the compiler will generate an error message. Illegal to declare a const member function that modifies a data member
class Point { int x,y; public : void setx(int xx) {x=xx;;} int getx( ) const {return x;} };
U.K.R., 2008 OOP
const(read only) member function, Any attempt to modify the member variables is an error
85
Constant Functions
const member functions can be invoked on const as well as non-const objects but non-const member functions can be invoked on non-const objects only
class Point { int x,y; public : void setx(int xx) {x=xx;;} int getx( ) const {return x;} }; const Point cp; Point p; int x = cp.getx(); //OK cp.setx(2); //Error x = p.setx(2); //OK p.getx(); //OK
U.K.R., 2008
OOP
86
class Point { mutable int x; public : void setx(int xx) {x=xx;} int getx( ) const { x++; //OK } };
U.K.R., 2008 OOP 87
U.K.R., 2008
OOP
89
U.K.R., 2008
U.K.R., 2008
OOP
94
Operator overloading
Example: the + (plus) operator in C++ behaves differently depending on the operands: 4+5 - integer addition 3.14 + 2.0 - floating point addition
Object + Oriented" - string concatenation
In C++, this is called operator overloading To overload means give it a meaning for user defined data type. Operator overloading, a way of achieving static polymorphism, which provides simply another way to make a function call for you
U.K.R., 2008 OOP 95
Operator Functions
Complex c1(2, 4), c2(3, 5), c3, c4; c3 = c1 + c2; C3=c1.operator+(c2); c4 = -c1; c4 = c1+c2*c3; Array a1(10), a2(10), a3, a4; a3 = a1+a2; a4 = -a1; if(a1 < a2) { // }
U.K.R., 2008
OOP
96
Operator Overloading
Operators that can be overloaded + ~ /= <<= -new[] ! %= == ->* delete[] * = ^= != -> / < &= <= . % > |= >= [] ^ += << && () & -= >> || new | *= >>= ++ delete
U.K.R., 2008
.*
OOP
?:
sizeof
97
Operator Functions
Operators can be interpreted as functions in C++ The number of arguments in the overloaded operators argument list depends on two factors
Whether its a unary operator or binary operator Whether the operator is defined as a global function or a member function
U.K.R., 2008
OOP
98
Operator Functions
Unary operator @ on object o will be interpreted as operator@(o) or o.operator@() Binary operator @ on object o1 and o2 will be interpreted as operator@(o1, o2) or o1.operator@(o2) Complex c1(2,4), c2(3,5),c3,c4; c3 = c1+c2; //will be interpreted as c3 = operator+(c1,c2); //OR c3 = c1.operator(c2); c4 = -c1; //will be interpreted as operator-(c1); OR c1.operator-()
U.K.R., 2008 OOP 99
Operator Overloading
Syntax of Operator overloading as non-member
Keyword Operator to be overloaded
Number of arguments for non-member operator function for Unary operator 1 Binary operator 2
U.K.R., 2008 OOP 100
Operator Overloading
Syntax of Operator overloading Class Member Number of arguments in a member function for
Unary operator 0 Binary operator 1 Operator to be overloaded
U.K.R., 2008
OOP
102
U.K.R., 2008
OOP
103
U.K.R., 2008
OOP
104
Implementation?
// Define prefix increment operator. Index Index ::operator++() { x++; return *this; } // Define postfix increment operator. Point Point::operator++(int) { Point temp = *this; ++*this; //or ++x; return temp; }
U.K.R., 2008 OOP 107
U.K.R., 2008
OOP
111
U.K.R., 2008
int f(Complex x, Complex y, Complex z) { Complex r1 = x+y+z; //r1 = x.operator+(y.operator+(z)); Complex r2 = x; //r2 = x; r2 += y; //r2.operator+=(y); r2 += z; r2.operator+=(z); }
Three objects are involved in a + operation Two objects are involved in a += operation
U.K.R., 2008 OOP 114
Mixed-Mode Arithmetic
To Handle Complex c1 = 2 + c2 we need to define operators of different types
class Complex { int r, i; public: Complex operator + (const Complex &); Complex operator += (const Complex &); }; Complex operator + (double, const Complex &);
void f (Complex x, Complex y) { Complex c1 = x+y; //c1 = x.operator+(y) Complex c2 = 2+x; //c2 = operator(2, x) }
U.K.R., 2008 OOP 115
Mixed-Mode Arithmetic
Two ways to Handle Complex c1 = c2+2
class Complex { public: Complex(int); Complex operator + (const Complex &); }; void f (Complex x) { Complex y = x+2; //y = x.operator+(Complex(2)) } class Complex { public: //no one argument constructor }; Complex operator + (const Complex & , double); void f (Complex x) { Complex y = x+2; //y = operator+(x, 2) }
U.K.R., 2008 OOP 116
Ambiguity
Ambiguity may occur of one argument constructor and operator functions both are defined
class Complex { public: Complex(int); Complex operator + (const Complex &); }; Complex operator + (const Complex & , double); void f (Complex x) { Complex y = x+2; //ambiguity, y = x.operator+(Complex(2)) or y = operator+(x, 2)? }
U.K.R., 2008
OOP
117
Explicit Constructor
Implicit conversion can be prevented by declaring constructor explicit
class Complex { public: explicit Complex(int); Complex operator + (const Complex &); }; void f (Complex x) { Complex y = x+2; // error Complex z = x+Complex(2); // ok }
U.K.R., 2008
OOP
118
Overloading = operator
class Stack { Solution private : int *a, size, top; class Stack { public : public : Stack(int sz) { Stack & operator = (const Stack &s) { top = -1; top = s.top; a = new int[size = sz]; delete a; } a = new int[size = s.size]; void push(int item) { for(int I = 0; I < size; i++) a[++top] = item; a[i] = s.a[i]; } return *this; int pop() { } return a[top--]; }; } };
s1 s2
a a
3 6 9 4
s1 s2
a a
3 6 9 4
Before s2=s1
U.K.R., 2008 OOP
After s2=s1
119
Overloading = operator
class String { private: char *buf; public: int length; String & operator=(const String &); }; String & String::operator=(const String & s) { if(this == &s) return *this; delete buf; length = s.length; buf = new char[length + 1]; strcpy(buf, s.buf); return *this; }
U.K.R., 2008
OOP
120
U.K.R., 2008
OOP
121
U.K.R., 2008
OOP
122
class Point { public: Point &operator=( Point & ); // Right side is the argument. ... }; // Define assignment operator. Point &Point::operator=( Point &pt) { x = pt. x; y = pt. y; return *this; // Assignment operator returns left side. }
U.K.R., 2008 OOP 123
[ ] operator Overloading
Array a(10); a[4] = 6; int x = a[4]; String s(C++); s[0] = J; Table t(4, 5); int x = t[2][3]; t[0][0] = 5;
Database db; db["user1"]= "abc"; db["user2"]= "xyz"; db["user3"]= "pqr"; if(db[user1] == passwdGiven) { // allow to login } else { // dont allow to login }
U.K.R., 2008
OOP
124
U.K.R., 2008
OOP
125
U.K.R., 2008
OOP
126
U.K.R., 2008
OOP
127
U.K.R., 2008
OOP
128
Database db; db["user1"]= "abc"; db["user2"]= "xyz"; db["user3"]= "pqr"; if(db.[user] == passwdGiven) { // allow to login } else { // dont allow to login }
129
Function that requires direct access should be a member unless there is a specific reason for it to be a non-member
U.K.R., 2008
OOP
130
Operation modifying state should be a member or a global function taking non-const reference =, +=, ++ are naturally defined as member If implicit conversion is desired, function must be non-member taking const reference or non reference
U.K.R., 2008 OOP 131
U.K.R., 2008
OOP
132
U.K.R., 2008
OOP
133
U.K.R., 2008
OOP
134
//cout.operator<<(str); cout.operator<<(x);
U.K.R., 2008
OOP
136
U.K.R., 2008
OOP
137
U.K.R., 2008
OOP
138
U.K.R., 2008
OOP
139
//cin.operator>>(str); cin.operator>>(x);
U.K.R., 2008
OOP
141
Conversion operator
One argument constructor is a conversion operator It can convert user define/built-in data type to user defined data type
class String { public: String(char *); }; Class Table { /**/ }; class Matrix { public: Matrix(Table); };
Conversion operator
It can not specify
User defined to built in conversion Conversion from a new class to old class without modifying the old class
//conversion to char *
Conversion operator
class Index { int i; public: Index(int); operator int(); operator Integer(); }; void f () { Index in(4), out(10); int x = in; int y = in + out in = 2; Integer i; i = in; }
U.K.R., 2008
Conversion operator
class Array { int *buf; public: Array(int); operator int*(); }; void f () { Array a(10); int *arr = a; }
//conversion to int*
//arr = int*(a)
U.K.R., 2008
OOP
145
Array::operator int*() { int *temp = new int[length]; for(int i = 0; i < length; i++) temp[i] = buf[i]; return temp; }
U.K.R., 2008 OOP 146
Ambiguity
An assignment of a value of type V to an object X is legal if
V is X Or there is an unique conversion from V to X
class Index { /**/ Index(int); // int to Index conversion }; class Integer { /**/ Integer(int); // int to Integer conversion }; void f(Index); Void f(Integer); void h() { f(2); //error, ambiguous, f(Integer(2)) or f(Index(2)) ? }
U.K.R., 2008 OOP 147
Ambiguity
If both user-defined conversions and user-defined operators are defined, it possible to get ambiguity
class Integer { /**/ Integer(int); // int to Integer conversion operator int(); // Integer to int conversion Integer operator+(Integer, Integer); }; void f(int x, Integer y) { x+y; //error, ambiguous: operator+(Integer(x), y) or x+int(y)? }
U.K.R., 2008
OOP
148
Multilevel conversion
Only one level of user defined implicit conversion is legal If multiple implicit conversions are required to construct a value, it must be handled explicitly
class Index { /**/ Index(int); // int to Index conversion }; Class Integer { /**/ Integer(Index); // Index to Integer conversion }; void f(Integer); void h(int i) { f(i); //error, f(Integer(Index(i))) not tried f(Integer(i)); //ok, f(Integer(Index(i))) f(Index(i)); //ok, f(Integer(Index(i))) }
U.K.R., 2008 OOP 149
Other issues
Return type is not used as overload resolution
class Integer { public: Integer(double); }; Integer operator +(Integer, Integer); vid f(doube d1, double d2) { Integer q1 = d1 + d2; //double precison add Integer q2 = Integer(d1) + d2; //force Integer add }
U.K.R., 2008
OOP
150
Other issues
If both sides of an assignment or assignment have been determined, both types are used to resolve resolution
class Real { public: operator double(); operator int(); }; void f(Real r) { double d = r; // d = r.double(); int i = r; // i = r.int(); d = r; // d = r.double(); i = r; // i = r.int() }
U.K.R., 2008
OOP
151
Things to remember
It is not a good idea to define a conversion operator without significant reason When used in excess, they lead to ambiguity Rely on either user-defines conversions or user-defined operators, but not both
U.K.R., 2008
OOP
152
Standard implementations of new and new[] do not initialize memory returned Default behavior can be overridden by redefining new operator
void * operator new (size_t sz); int *x = new int; float *f = new float; double *d = new double;
U.K.R., 2008
U.K.R., 2008
OOP
154
Calls operator new(sizeof(Point)) or Point::operator new(sizeof(Point)) If new operator call is successful (memory allocation is successful), it calls Points default constructor Specialized allocator/deallocator for a class can be provided
class Point { public: void *operator new(size_t); };
operator new is implicitly static, consequenctly it does not have this pointer
U.K.R., 2008 OOP 155
U.K.R., 2008
OOP
156
void * operator new[] (size_t sz); int *x = new int[2]; float *f = new float[4]; double *d = new double[10]; // operator new[](sizeof(int)); // operator new[](sizeof(float)); // operator new[](sizeof(double));
U.K.R., 2008
OOP
157
U.K.R., 2008
OOP
158
void operator delete (void *); void operator delete (void *p) { if(p) { // deallocate memory allocated by new; } }
U.K.R., 2008
OOP
159
Overloading () operator
One popular use of () operator is as subscripting operator for multidimensional arrays
class Table { int ** buf; public: int& operator() (const int &, const int &); }; Table matrix(10, 10); int x = matrix(4, 5); matrix(2, 3) = 8;
Implementation
int& Table::operator() (const int &i, const int &j) { return buf[i][j]; }
U.K.R., 2008
OOP
160
Overloading () operator
Function Objects
Objects used as a function class Point { int x, y; public: void operator() (const int &, const int &); }; void operator() (const int &xx, const int &yy) { x = xx; y = yy; } Point p(3, 4); p(4, 5);
U.K.R., 2008
Overloading
operator
Dereference operator can be used as unary postfix operator Given a class class Ptr { public: X* operator->(); }; Objects of Ptr can be used to access members of class X in a very similar manner to the way pointers are used void f(Ptr p) { p->m = 2; }
// (p.operator->())->m = 2;
U.K.R., 2008
OOP
162
Overloading
Example class Point { private: int x, y; public: Point(); Point(int, int); int getx(); void setx(int); };
operator
class PPtr { Point *ptr; public: PPtr(); PPtr(Point &); Point* operator->(); };
Overloading
operator
For ordinary pointers, use of -> is synonymous with some uses of unary * and []. Given Y *p it holds that p->m == (*p).m == p[0].m Such gurantee is not provided for user-defined operators class APtr { Array *arr; public: APtr(); APtr(Array &); Array* operator->(); Array& operator[](int); Array& operator*(); Array& operator++(); };
U.K.R., 2008 OOP
Array *a = new Array[4]; APtr ptr(*a); for(i = 0;i<4;i++) cout << ptr[i]; ptr++; ptr->length; cout << *ptr;
164
U.K.R., 2008
OOP
165
4. Inheritance
By using the concepts of inheritance, it is possible to create a new class from an existing one and add new features to it. Inheritance provides a mechanism for class level Reusability. Semantically, relationship. inheritance denotes an is-a
U.K.R., 2008
OOP
166
Inheritance
Person Name Height Age
Inheritance
Inheritance is the relationship between a class and one or more refined version of it. The class being refined is called the superclass or base class and each refined version is called a subclass or derived class. Attributes and operations common to a group of subclasses are attached to the superclass and shared by each subclass. Each subclass is said to inherit the features of its superclass.
U.K.R., 2008 OOP 168
The visibility-mode is optional. It may be either private or public or protected(default it is private) This visibility mode specifies how the features of base class are visible to the derived class.
U.K.R., 2008 OOP 169
Inheritance
Types of Inheritance Simple or Single Inheritance Multi level or Varied Inheritance Multiple Inheritance Hierarchical Inheritance Hybrid Inheritance Virtual Inheritance
U.K.R., 2008
OOP
170
Student
Student
CS -Student
U.K.R., 2008
Multiple Inheritance
A class is inheriting features from more than one super class Class Part-time Student is derived from two base classes, Employee and Student
class Employee { /**/ }; class Student { /**/ }; class Part-time Student : public Employee, public Student { /**/ };
OOP 173
Employee
Student
Part-time Student
U.K.R., 2008
Hierarchical Inheritance
Many sub classes are derived from a single base class The two derived classes namely Student and Employee are derived from a base class Person.
class Person { /**/ }; class Student : public Person { /**/ }; class Employee : public Person { /**/ };
OOP 174
Person
Student
Employee
U.K.R., 2008
Hybrid Inheritance
In this type, more than one type of inheritance are used to derive a new sub class Multiple and multilevel type of inheritances are used to derive a class PG-Student class Person {
/**/ Person
}; class Student : public Person {
/**/
}; class Gate Scorer {
Student
Gate_Scorer
/**/
}; class PG - Student : public Student public Gate Scorer {
PG_Student
U.K.R., 2008
/**/
OOP
};
175
Virtual Inheritance
Person
class Person {
/**/
}; class Student : public Person {
Student
Employee
/**/
}; Class Employee : public Person {
/**/
};
Part-time Student
class Part-time Student : public Student, public Employee {
/**/
};
U.K.R., 2008 OOP 176
Virtual Inheritance
A sub class is derived from two super classes which in-turn have been derived from another class. The class Part-Time Student is derived from two super classes namely, Student and Employee. These classes in-turn derived from a common super class Person. The class Part-time Student inherits, the features of Person Class via two separate paths
U.K.R., 2008
OOP
177
Inheritance contd,
Four things you might find in an Inheritance Hierarchy
Super class is too general to declare all behavior, so each subclass adds its own behavior. Super class legislates an abstract behavior and therefore delegates implementation to super class. Super class specifies behavior, subclasses inherit behavior. Super class specifies behavior, subclasses choose to override behavior.
U.K.R., 2008
OOP
178
If we want an instance variable to be available for subclasses to change it, then we can choose access specifier protected. The following examples illustrates the usage of these access specifiers.
U.K.R., 2008
OOP
179
} void global_fun(Y *p) { p->priv = 1; //Error : priv is private of X p->prot = 2; //Error : prot is protected //and the function global_fun( ) // is not a friend or a member of X or Y p->publ =3; // Ok }
OOP
180
Class A
private : int a1;
Class B
private : int b1;
Class B: Public A
private : int b1;
Public Derivation
U.K.R., 2008 OOP 181
} void global_fun(Y *p) { p->priv = 1; //Error : priv is //private of X p->prot = 2; //Error : prot is // protected and the function global_fun( ) // is not a friend or a member of X or Y p->publ =3; // Ok }
OOP
182
Class B
private : int b1; protected : int b2; public : int b3;
Class B : Protected A
private : int b1; protected: int a2; int b2,a3; public: int b3;
Protected Derivation
U.K.R., 2008 OOP 183
Y::mderived( ) { priv =1; //Error priv is private and //cannot be inherited prot =2; // Ok publ=3; // Ok } void global_fun(Y *p) { p->priv = 1; //Error : priv is //private of X p->prot = 2; //Error : prot is //protected and the function global_fun( ) // is not a friend or a member of X or Y p->publ =3; // Error, protected }
OOP
184
Class B
private : int b1; protected : int b2; public : int b3;
Class B : private A
private : int b1; int a1,a2,a3; protected: int b2; public: int b3;
Private Derivation
U.K.R., 2008 OOP 185
class Z: public Y { public : void f() { prot=2;//error, prot is private to Y } }; void global_fun(Y *p) { p->priv = 1; //Error : priv is //private of X p->prot = 2; //Error : prot is //protected and the function global_fun( ) // is not a friend or a member of X or Y p->publ =3; // error }
OOP
186
U.K.R., 2008
OOP
187
188
B::B( ) Fires D::D( ) Fires B::B( ) Fires D::D(int) Fires B::B(int) Fires D::D(int, int) Fires
189
U.K.R., 2008
OOP
190
class Employee { protected : char name[50]; public : void printDetails() { cout << name; } class Manager : public Employee { protected: int type; }
class Manager : public Employee { public : void printDetails() { Employee::printDetails();cout << type; } }
U.K.R., 2008
OOP
191
5. Polymorphism
Introduction:
In this Module one of the most important concept of OOPS i.e Polymorphism is discussed. Objective: After completing this module,you will be able to understand, Static Polymorphism Overloaded Functions Overloaded Operators Dynamic Polymorphism Virtual Functions
U.K.R., 2008 OOP 192
Polymorphism
Greek word meaning forms. many or multiple
In programming languages, polymorphism means that some code or operations or objects behave differently in different contexts It provides a single interface to entities of different types.
U.K.R., 2008
OOP
193
Types of polymorphism
Polymorphism
Static Polymorphism
Dynamic Polymorphism
Function Overloading
Operator Overloading
Virtual Function
U.K.R., 2008
OOP
194
Polymorphism
Compiler determines a location in memory is called binding Connecting a function call to a function body is called Binding The location may represent the following Variable names bound to their storage memory address (offset) Function names bound to their starting memory address (offset) Two kinds of binding Compile-Time Binding Run-Time Binding
U.K.R., 2008 OOP 195
Static Polymorphism
Compile-time binding or early binding is called as static polymorphism. Compile-Time Binding means Compiler has enough information to determine an address (offset) Named variables have their addresses hard-coded during compilation Global variables are given offset from start of global data area Local variables are given offset from top of stack Objects are given offset from start of object data executable code contains address references
U.K.R., 2008 OOP 196
Function Templates
To create generic functions that admit any data type as parameters and return a value without having to overload the function with all the possible data types. Until certain point they fulfill the functionality of a macro. Compact way to make overloaded functions InstantiationGenerate separate functions for different data types.
U.K.R., 2008
OOP
197
Function Templates
Keyword for declaring function template Keyword class Name of the template data-type Function parameters of type template, primitive or user-defined
template < class identifier > ReturnType FunctionName(arguments of type identifier) template < class T > // or template< typename T > T square( T value1 ) { return value1 * value1; }
U.K.R., 2008 OOP 198
Function Templates
Examples: Finding the absolute value of a variable
Definition: template <class Type> Type abs(Type val) { if (val >= 0) return val; else return val; }
U.K.R., 2008 OOP 199
Function Templates
// definition of function template maximum In main( ) template < class T > maximum( int1, int2, int3 ) // or template < typename T > T maximum( T value1, T value2, T value3 ) { maximum( double1, double2, double3 ) T max = value1; if ( value2 > max ) max = value2; if ( value3 > max ) max = value3; maximum( char1, char2, char3 ) return max; } Output Maximum value Input values 1, 2, 3 3 1.1 , 2.1, 1.8 2.1 A, B, C C
U.K.R., 2008 OOP 200
U.K.R., 2008
OOP
201
template<> bool less<>(const char *a, const char *b) { return strcmp(a,b); }
U.K.R., 2008 OOP
template<> bool less(const char *a, const char *b){ return strcmp(a,b); }
202
//swap for Stack template<> void swap(Stack &a, Stack &b) { a.swap(b); }
U.K.R., 2008
OOP
203
Type Conversion
An Example main( ) { Index i(3); int x; x=i; i=x; } //int to Index conversion //Index to int conversion //int to Index conversion
Type Conversion
Objects of a given class type can be converted to objects of another type This is done by constructing an object of the target class type from the source class type and copying the result to the target object. This process is called conversion by constructor Objects can also be converted by user-supplied conversion functions
Conversion required Conversion takes palce in Conversion takes palce in
Type Conversion
class Index { int x; public : Index(int i):x(i){} operator int() { return x; } }; main( ) { Index i(3); int x; x=i; i=x; }
U.K.R., 2008
OOP
206
Type Conversion
#include <string.h> class String { public: // Define constructor that converts //from type char * String( char *s ) { strcpy( _text, s ); } // Define operator conversion function //to type char * operator char *() { return _text; } } private: char _text[80]; };
U.K.R., 2008 OOP
int main() { String s( "abcd" ); char *str = "efgh"; strcpy(str,s); //strcpy(str, char*(s)); //String to char* conversion }
207
int main() { String s( "abcd" ); char *ch = "efgh"; return s == ch; //ambiguity operator ==(s, String(ch)) or char*(s) == ch ? }U.K.R., 2008 OOP
208
Composition
Classes having objects of other classes as their data members - composite classes class y
{ class X { int i; public: x() { i = 0; } void set(int j) { i = j; } int read() const { return i; } };
U.K.R., 2008 OOP
int i; public: X x; Y() { i=0;} void f(int j) { i=j;} int g() const { return i;} }; int main() { Y y; y.f(5); y.x.set(10); }
210
U.K.R., 2008
No matters style of call, function name and object type serve as basics for function body selection. All three calls of f( ) on derived class object d through the object, through a base class pointer and through a derived class pointer provides the same result.
212
class Employee { protected : char name[50]; public : void printDetails() { cout << name; } class Manager : public Employee { protected: int type; public : void printDetails() { Employee::printDetails(); cout << type; } }
U.K.R., 2008
void main( ) { Employee e(John), *eptr; Manager m(Mike,1); eptr = &e; //obvious eptr->printDetails();//Employee::printDetails() eptr = &m;//legal as Manager is an Employee eptr->printDetails(); //Employee::printDetails }
OOP
213
class Shape { public : void draw(); }; class Triangle : public Shape { public : void draw(); }; class Rectangle : public Shape { public : void draw(); }; class Circle : public Shape { public : void draw(); };
U.K.R., 2008
void main( ) { Shape *arr[3]; arr[0] = new Triangle; arr[1] = new Rectangle; arr[2] = new Circle; for(int i=0;i<3;i++) //draw all objects arr[i]->draw(); }
OOP 214
U.K.R., 2008
OOP
216
int main() { Base *ptr B; Derived0 D0; Derived1 D1; ptr=&B; ptr->fun(); ptr=&D0; ptr->fun(); ptr=&D1; p->fun(); return 0; }
217
Virtual functions should be member functions. To construct an object , a constructor needs the exact type of the object it is to create. So a constructor can not be virtual but a destructor can be.
U.K.R., 2008
OOP
218
output
Executing B::f() object d was created successfully. Executing D::f()
U.K.R., 2008
OOP
219
U.K.R., 2008
OOP
220
As p is of type B*, p is bound to Bs data members and methods, including constructors and destructors rather than to Ds methods . When f exits B::~B frees the 5 bytes. D::~D() fails to fire.
U.K.R., 2008
OOP
221
Solution
class B { char * ptrB; public: B() { ptrB=new char[5]; cout<<B allocates 5 bytes\n; } virtual ~B() { delete []ptrB; cout<<B frees 5 bytes\n; } }; class D: public B { char*ptrD; public: D( ) : B() { ptrD=new char[1000]; cout<<D allocates 1000 bytes\n; } ~D() { delete[] ptrD; cout<< D frees 1000 bytes\n; } };
U.K.R., 2008
OOP
222
The default argument to be passed to foo() is not determined at run time, rather it is determined at compile time and is based on the type of the object through which the function is being invoked.
U.K.R., 2008 OOP 224
U.K.R., 2008
OOP
225
U.K.R., 2008
class Shape3D : public Shape { public: virtual float volume(); // Pure Virtual function }; class Cube : public Shape3D { public: void draw(); float volume(); // concrete functions };
227
Standard conversions dont convert derived class pointers to base class pointers with private/protected derivation. Always use public inheritance with polymorphism.
OOP
228
Base b1;
Base Members vptr
Base::f2() Base::f3()
Derived d1;
Base Members vptr Derived Members
Derived vtbl;
Base::f1() Derived::f2() Base::f3() Derived::f4()
U.K.R., 2008
OOP
230
Base b1; Derived d1; Base *p=&d1; p->f4(); // illegal Derived *q=&d1; q->f4() ;// legal
With the help of base class pointer, we cant access any derived class members.
231
U.K.R., 2008
OOP
233