Sie sind auf Seite 1von 233

Object Oriented Programming

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

BPCL C Algol68 Algol68 Simula67 Simula67 (Smalltalk) (Ada) (LISP)


U.K.R., 2008 OOP 5

C++

Strengths and Weakness of C


Strengths
   

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

Examples of OOP Language


Pure Object Oriented Programming Languages
 

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.

Languages with OO Extensions


  

Languages with OO look and feel




U.K.R., 2008

OOP

10

Differences between C and C++


OO programming constructions Function prototyping Default parameter values Reference parameters Enumeration names Use of const Inline functions Block declarations Different syntax for cast operator Function and operator overloading New syntax for comments Operators for I/O streams New libraries
U.K.R., 2008 OOP 11

Key Words for C and C++


C and C++ Key Words auto break case default do double float for goto register return short struct switch typedef volatile while Additional C++ Key Words asm catch class new operator private this throw try char else if signed union const enum int sizeof unsigned continue extern long static void

delete friend protected public virtual

inline template

U.K.R., 2008

OOP

12

Non-Object Oriented Extension from C to C++

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

struct A { int x; }; A a; enum E {ee}; E e;


15

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:
 

C style cast Function notation cast

int i, j; //C style float g = (float)i/2; //function notation float h = float(j)/2


U.K.R., 2008 OOP 17

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:
 

Impossibility of accidental modification of data Increases readability


OOP 20

U.K.R., 2008

Const and #define


Incorrect Result:


Using #define

#define x 4-2 main( ) { int y = x*x; }




//incorrect, y = 4-2*4-2 = -6

Using const

const int x = 4-2; main( ) { int y = x*x; }


U.K.R., 2008

//correct, y = 2*2 = 4

OOP

21

Const and #define


Impossibility of creating variable conditionally
main( ) { int n; cin >> n; if(n > 0) { #define v n; cout << v*v; } else { #define v -n; cout << v*v; } } main( ) { int n; cin >> n; if( n > 0) { const int v = n;/*do rest thing*/ } else { const int v = -n;/*do other thing*/ } }
U.K.R., 2008 OOP 22

Constants and Pointers


int x = 4,y = 6; const int *p = &x; //variable pointed by p, is const, but pointer p is not *p = 8; //error p = &y; //ok int const *q = &x; //same as p

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

DataType & ReferenceVariable = OriginalVariable


OrigialVariable

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

Properties of a reference variable


Cannot exists independentlymust be initialized when they are created Cannot be manipulated independentlyexcept initialization operation, all the operation will be implied on original variable Can be viewed as a const pointer without dereferencing notation i. e. object/variable to which a reference refers cannot be changed.
U.K.R., 2008 OOP

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

Constants and References


Example:
int x = 4; const int &p = x; //read only alias for x p = 8; //error x = 8; //ok const int y = 6; int & q = y; const int &r = y; r = 10; y = 12;
U.K.R., 2008

//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

void change(int a, int b) { int temp; temp = a; a = b; b = temp; }


U.K.R., 2008

//a,b formal params

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

void change(int &a, int &b) { int temp; temp = a; a = b; b = temp; }


U.K.R., 2008

//a,b formal args

temp

OOP

31

Usage of References
Avoid unnecessary copying
float deteminant(Matrix &m) { /*find determinant of matrix m here*/ }

Danger with references


Function invocation does not indicate that references are used. So passed argument may be changed unknowingly.
float deteminant(const Matrix &m) { /*find determinant of matrix m here*/ }

Possible solutionuse const

Possibility to write generic function


more that an one value can be retrieved from a a function
int f(int a, int b, int c, int &max, int &min); //take three integers and return sum, max and min void find(int ele, int *arr, bool &found, int &location); //find an element ele in array arr and if found return location
U.K.R., 2008 OOP 32

Return by References

int x = 2; int &f() { return x; }

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

inline ReturnType FunctionName(Parameters) { // Body of a main function }

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; // }

inline int fact(int n { return (n < 2?1:n*fact(n-1)); }


void main( ) { compiler // a = fact(5); b = fact(4); cin >> n; c = fact(n); // }
U.K.R., 2008

void main( ) { // a = 120; b = 4*fact(3); cin >> n; c = fact(n); // }


OOP

//impossible to substitute
36

Inline Functions versus Macros


Inline functions: parsed by the compiler Macros : expanded by the preprocessor. E.g., #define max(x,y) ((x>y)?x: y) Limitation with macro: Macros are not functions and errors are not checked at compilation time until it is used.

U.K.R., 2008

OOP

37

Inline Functions versus Macros


Reasons why Inline functions are better than macros: Follow all the protocols of type safety enforced on
normal functions.
#define div(x,y) (x/y) void main() { cout << div(5,2); //wrong result 2 } inline float div(float a, float b) { return a/b ;} void main() { cout << div(5,2); //correct result 2.5 }

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 Functions versus Macros


# define SQUARE(num) num * num
Output

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 &);

Overloaded function resolution


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

//ambiguity:which sum? sum(int(1.1), int(1.1)) or sum(float(1.1), float(2.2)?


OOP 41

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

int myFunction(int x = 1,int y = 2,int z = 3)


myFunction(3); //x = 3, y and z get defaults (rightmost) myFunction(3, 5); //x = 3, y = 5 and z gets default myFunction(3, 5, 7); //x = 3, y = 5 and z = 7

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

Object Oriented Programming


 Program is composed of a collection of individual units, or objects, as opposed to a traditional view in which a program is a list of instructions to the computer
Object B

Data variable
Object A Object C

Member Function Data variable Member Function


U.K.R., 2008 OOP

Data variable Member Function


45

Object Oriented programming?


In an object oriented environment, software is a collection of discrete objects that encapsulate their data as well as the functionality to model real-world objects. Objects: Packaging data and functionality together into units within a running computer program; The basis of modularity and structure in an object-oriented computer program. Self contained and should be easily identifiable.

U.K.R., 2008

OOP

46

Benefits of Object Orientation


Modularity: Since the whole system is being modeled as classes and various methods are divided according to the respective functionalities in respective classes, modularity increases. Deferred Commitment: Since classes can be modified without modifying the actual code where the classes are being used, flexibility towards the commitment increases (Easier maintenance). The internal workings of an object can be redefined(easily) without changing other parts of the system. Reusability: Since defining classes through inheritance helps in reusability thus faster production.

U.K.R., 2008

OOP

47

Benefits of Object Orientation


Higher Quality: Since deriving classes from existing classes which are working successfully. Reduced cost: Because of reusability Increased Scalability: Easier to develop (integrate)large systems from well tested smaller systems.

U.K.R., 2008

OOP

48

Classes and Objects


Logical Abstraction A Class is a description of common properties of objects that belong to the class i.e., collection of objects with common characteristics. Create objects of various classes. These are the physical existence. For individual objects, are the data and functions replicated?

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

Atrributes and their class

Student roll::Integer name::String address::String birthDate::Date attributes

PC hdd::Component ram::Memory Mouse::InputDevice keyboard::OutputDevice attributes

Atrributes and their class


U.K.R., 2008 OOP

Atrributes and their class


52

Classes
Operations
Rectangle area() grow() move isEmpty() Operations TeperatureSensor

operations

reset() setAlarm(t: Temperature) Value(): Temperature Operations

operations

Register endSale() enterItem(id: ItemId, qty: Integer) pay(cashTendered: Money) 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.

+execute() +rollback() #priority() -timestamp()

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

Rectangle tl: Point rb: Point area(): Float

Circle radius: Float center: Point area(): Float

Polygon points:List area(): Float display()

Customer

Supplier

Employer

Square leaf class


U.K.R., 2008

derived/child class

OOP

56

Polymorphism
Many(poly-) forms(-morph) Function overloading Operator overloading Inheritance Virtual function

U.K.R., 2008

OOP

57

Classes & Objects


p1 struct Point { int x, y; float distance(Point); /**/ }; void main( ) { Point p1, p2; p1.x=2; p1.y=4; p2.x=6; p2.y=8; float d = p1.distance(p2); } x 2 y 4 x 6 p2 y 8

Objects

Initialization of member variables

U.K.R., 2008

OOP

58

Classes & Objects


c1 struct Complex { double real, img; Complex add(Complex); /**/ }; void main( ) { Complex c1, c2; c1.real=1.5; c1.img=3.4; c2.real=5.6; c2.img=8.8; Complex c3 = c1.add(c2); } real img 1.5 3.4 c2 real img 5.6 8.8

Objects

Initialization of member variables

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

Inline Member Functions


If a member function is implemented outside the class braces, it is not inlined by default, but it can be defined as inline using the inline keyword.
class Point { public: int x, y; void setx(int); void sety(int yy) {y=yy;} float distance(Point); /**/ }; void Point::setx(int xx) {x=xx;} inline float Point::distance(Point p) { return sqrt((x-p.x)*(x-p.x)+(y-p.y)*(y-p.y); }
U.K.R., 2008 OOP

Member function prototype declaration

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

void setx(int xx) { x = xx; }

void setx(int xx, Point *this) { this->x = xx; }

setx(2, &p1); setx(6, &p2);


U.K.R., 2008 OOP

void setx(int x) { this->x = x; }


63

Constructors and Destructors


class Point { private: int x, y; public: void setx(int x) {this->x=x;} void sety(int yy) {y=yy;} float distance(Point); /**/ }; void main( ) { Point p1, p2; p1.setx(2); p1.sety(4); p2.setx(6); p2.sety(8); float d = p1.distance(p2); }
U.K.R., 2008 OOP

Initialization of member variables

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

Dynamic Memory Allocation


int *x; x = new int[100]; float *f; f = new float[10]; char *str; str = new char[4]; str[0] = C; str[1] = +; str[2] = +; str[3] = \0; class Point { int x, y; }; Point *ptr; ptr = new Point[5]; for(int i=0;i<5;i++) { Point p; ptr[i] = &p; }

delete(x); delete(f); delete(str); delete(ptr);

U.K.R., 2008

OOP

68

Constructors with arguments


Parameters can be passed to the constructors
class Point { public: int x, y; Point(int i, int j); }; Point::Point(int i, int j) { x=i;y=j; } void main( ) { Point p1(10, 20); Point p2 = Point(30, 40); Point p3 = p2; }
U.K.R., 2008 OOP

Parameterized Constructor

Constructor called implicitly

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;

Two arguments: Point p1(2,4) Copy constructor: Point p2=p1


70

Point(const Point & i) {x=i.x;y=i.y;};


U.K.R., 2008 OOP

Constructors with default arguments


Constructors can be defined with default arguments
class Point { public: int x, y; Point(int i, int j=10) { x=i;y=j; } }; void main() { Point p1(1); Point p2(8, 9); } Object p1 Object p2 x= 1 y= 10 x= 8 y= 9 Default value for j=10 (Used by the object p1)

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

Copy Constructors contd.,


class aClass { public: int x; aClass(){ } aClass(int i) {x=i;} aClass(aClass &j) {x=j.x;} }; void main() { aClass o1(10); aClass o2(o1); aClass o3=o1; aClass o4; o4=o1; }

Objects

o1 x=10

o2 x=10
OOP

o3 x=10

o4 x=10
73

U.K.R., 2008

Importance of Copy Constructors


class Stack { private : int *a, size, top; public : Stack(int sz):top(-1) { top = -1; a = new int[size=sz]; } void push(int item) { a[++top]=item; } int pop() { return a[top--]; } };

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

Stack s1(4), s2=s1;


s2
U.K.R., 2008 OOP

top size a

After s2=s1
74

top

Importance of Copy Constructors


class String { int length; char *buf; public: String(int size) { buf = new char[(length = size)+1]; } };

Solution
class String { String(const String &str) { length = str.length; buf = new char[length+1]; strcpy(buf, str.buf); } };

String s1(4), s2=s1;


s1

buf length buf s2 length

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

For each object, an instance of each non-static data member is created

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

Static Members contd.


Only one copy of static data member will exist irrespective of the number of objects created Static functions can access only static variables Efficient when single copy of data is enough May seem like global variables, but have class scope Only accessible to objects of same class

U.K.R., 2008

OOP

80

Static Members contd.,


Static Member Example
class SavingsAccount { private: int currentBal; public : static int RateofInt; SavingsAccount(int b) {currentBal=b;} }; int SavingsAccount::RateofInt=10; SavingsAccount myAccount(0), yourAccount(1);

Shared by all objects Object yourAccount

Object myAccount
U.K.R., 2008

currentBal=0
OOP

currentBal=1
81

Static Members contd.,


Static Member Example
class Car { private: const int serialNo; public : static int nextSerial; Car():serialNo(nextSerial++) {} }; int Car::nextSerial=10; Car aCar, anotherCar;

Shared by all objects Object anotherCar

Object aCar
U.K.R., 2008

serialNo=10
OOP

serialNo=11
82

Static Member function


Static Member function example

class Car { public : static int nextSerial; static void reset() { nextSerial = 0; } };

U.K.R., 2008

OOP

83

Static Members contd.,


Static Data Members:
class SavingsAccount Only one copy should { be available as all private: objects should have char name[30]; same Interest rate float total; float CurrentRate; public: To make CurrentTate accessible to all objects SavingsAccount(); void EarnInterest() { Declare CurrentRate as total + = CurrentRate * total; static float CurrentRate; } }
U.K.R., 2008 OOP 84

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

Mutable data members

class Point { mutable int x; public : void setx(int xx) {x=xx;} int getx( ) const { x++; //OK } };
U.K.R., 2008 OOP 87

Mutable data members


class Point { mutable int cnt; public : void setx(int xx) { ... count(); } int count( ) const { return cnt++; //OK } };
U.K.R., 2008 OOP 88

Friend Functions and Classes


A friend of a class can access even its private members. Useful when one class wants to see the private member variables of another class, even though those variables should not be made public Friend can be
A non-member function A member function of a class An entire class

U.K.R., 2008

OOP

89

Non-member as a friend example


void f() { /**/ } class X { friend void f(); };

A non-member function can be a friend of any number of classes


U.K.R., 2008 OOP 90

Non-member as a friend example


class Humidity; class Temperature { public: friend void PrintWeather(Temperature &t, Humidity &h); }; class Humidity { public: friend void PrintWeather(Temperature &t, Humidity &h); }; void PrintWeather(Temperature &t, Humidity &h) { //print both temperature and humidity }
U.K.R., 2008 OOP 91

Member as a friend example


class Y { friend void X::f(); };

class X { void f(); };

A member function can be a friend of any number of classes


U.K.R., 2008 OOP 92

Member as a friend example


class Node { private: int data, key; // ... friend void BinaryTree::find(int); // BinaryTree::key() can now access data directly }; class BinaryTree { private: Node *root; int find(int key); }; int BinaryTree::find(int key) { // check root for NULL... if(root->key == key) { // no need to go through an accessor function return root->data; } // perform rest of find }
OOP 93

U.K.R., 2008

Class as a friend example


class X { void f(); }; class Y { friend class X; };

A class can be a friend of any number of classes

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) { // }

Matrix m1(2, 4), m2(4, 3), m3; m3 = m1 + m2; Matrix m4 = m1*m2;

String s1(C++), s2(Java); String s3 = s1 + s2;

Operators on built-in data types can not be overloaded

U.K.R., 2008

OOP

96

Operator Overloading
Operators that can be overloaded + ~ /= <<= -new[] ! %= == ->* delete[] * = ^= != -> / < &= <= . % > |= >= [] ^ += << && () & -= >> || new | *= >>= ++ delete

Operators that can not be overloaded

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

ReturnType operator OperatorSymbol (argument list) { \\ Function body }

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

ReturnType classname :: operator OperatorSymbol (argument list) { \\ Function body }


U.K.R., 2008 OOP 101

Unary Operators Overloading


To declare a unary operator function as a nonstatic member

return-type operator op()


To declare a unary operator function as a global function

ret-type operator op(arg )

U.K.R., 2008

OOP

102

Unary (minus) operator overloading


Using member function
class Complex { private: int real, img; public: /**/ Complex operator -() { Complex temp; temp.real = -real; temp.img = -img return temp; } };

Usage: Complex c1(2,4), c2; c2 = -c1; //c1.operator -() is called

U.K.R., 2008

OOP

103

Unary (minus) operator overloading


class Array { private: int *buf, length; public: /**/ Array operator -() { Array temp = *this; for(int i=0;i<temp.length;i++) temp.buf[i] = -temp.buf[i]; return temp; } };

Usage: Array a1(10), a2; a2 = -a1; //a1.operator -() is called

U.K.R., 2008

OOP

104

Pre-increment operator overloading


class Index { private: int x; public: /**/ // Declare prefix increment operators. Index operator++(); }; Usage: Index in, out; ++in; //in.operator ++() is called out = ++in;
U.K.R., 2008 OOP 105

Post-increment operator overloading


class Index { private: int x; public: /**/ // Declare postfix increment operators. Index operator++(int); }; Usage: Index in, out; out++; //out.operator ++(int) is called in = out++; //out.operator ++(int);
U.K.R., 2008 OOP 106

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

Unary Operators Overloading


Using non-member function
class Complex { private: int real, img; public: /**/ friend Complex operator -(Complex); }; Complex operator -(const Complex &c) { Complex temp; temp.real = -c.real; temp.img = -c.img return temp; }
U.K.R., 2008 OOP 108

Unary Operators Overloading


Using non-member function
class Array { private: int *buf, length; public: /**/ friend Array operator -(Array); }; Array operator -(const Array &a) { Array temp = a; for(int i=0;i<temp.length;i++) temp.buf[i] = -temp.buf[i]; return temp; }
U.K.R., 2008 OOP 109

Unary Operators Overloading


Using non-member function
friend Index operator++(Index & ) // Prefix increment friend Index operator++(Index &, int ) // Postfix increment
//using friend function friend Index operator++(Index & i) { i.x++; //i.x is private, but friend function can access it return i; } //withou using friend function Index operator++(Index & i) { i.set(i.val()+1); //increment using reader and writer function return i; }
U.K.R., 2008 OOP 110

Binary Operator Overloading


To declare a binary operator function as a nonstatic member, you must declare it in the form:

ret-type operator op( arg )


To declare a binary operator function as a nonmember function, you must declare it in the form:

ret-type operator op( arg1, arg2 )

U.K.R., 2008

OOP

111

Binary + Operator Overloading


class Complex { int r, i; public: Complex operator + (const Complex &); Complex operator * (const Complex &); }; class Complex { public: int r, i; /**/ Complex operator + (const Complex & c) { Complex temp; temp.r = r+c.r; temp.i = i+c.i; return temp; } };
OOP 112

int main () { Complex c1(2,3), c2(4,5), c3; c3=c1+c2; c1=c1+c2*c3; c3=c1*c3; }

U.K.R., 2008

Binary += Operator Overloading


Minimize number of function directly manipulate objects
class Complex { int r, i; public: Complex operator + (const Complex &); Complex operator += (const Complex &); };

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); }

Computations of r1 and r2 are equivalent


U.K.R., 2008 OOP 113

Binary += Operator Overloading


Definition of += is simpler and efficient
Complex Complex::operator += (const Complex & c) { r += c.r; i += c.i; return *this; } Complex Complex::operator + (const Complex & c) { Complex temp = *this; return temp += c; }

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--]; }; } };

Stack s1(4), s2(5); s2=s1;

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

Overloading assignment operator


Assignment operator (=) is a binary operator. Its declaration is identical to any other binary operator, Exceptions: It must be a non-static member function. No operator = can be declared as a non-member function. It is not inherited by derived classes. A default operator= function can be generated by the compiler for class types if none exists (bitwise shallow copy) User defined operator= function performs member wise deep copy.

U.K.R., 2008

OOP

121

Predefined meaning of operators


A default operator= function can be generated by the compiler for class types if none exists (bitwise shallow copy) Declare it private to make them inaccessible
class X { private : X operator=(const X&); /**/ }; void f(X, a, X b) { a = b; //error: operator= private }

U.K.R., 2008

OOP

122

Overloading assignment operator

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

[ ] operator Overloading example


class Array { private: int *buf; public: int length; Array(); Array(int); int &operator[] (const int &); }; int &Array::operator[] (const int &index) { return buf[index]; }

Array a(10); a[4] = 6; //a.operator[](4) = 6; int x = a[4]; //x = a.operator[](4);

U.K.R., 2008

OOP

125

[ ] operator Overloading example


class String { private: char *buf; public: int length; String(); String(char *); char &operator[] (const int &); }; char &String::operator[] (const int &index) { return buf[index]; }

String s(C++); s[0] = J; //s.operator[](0) = J; char ch = s[1]; //ch = s.operator[](1);

U.K.R., 2008

OOP

126

[ ] operator Overloading example


class Table { private: Array * buf; public: int row, col; Table(); Table(int, int); Array & operator[] (const int &); }; Array & Table::operator[](const int &index) { return buf[index]; }

Table t(4, 5); int x = t[2][3]; t[0][0] = 5;

U.K.R., 2008

OOP

127

[ ] operator Overloading example


class Pair { public: String name, value; Pair(const String &n, const String &v); Pair(); }; class Database { private: Pair *list; public: int length; Database(); Database(const int&); String& operator[](const String&); };

U.K.R., 2008

OOP

128

[ ] operator Overloading example


String& Database::operator[](const String& s) { int index = -1; for(int i=0;i<length;i++) if(s == list[i].name) { index = i; break; } if(index != -1) return list[index].value; else { Pair *p = list; list = new Pair[++length]; for(int i=0;i<length-1;i++) list[i] = p[i]; list[length-1].name = s; return list[length-1].value; } }
U.K.R., 2008 OOP

Database db; db["user1"]= "abc"; db["user2"]= "xyz"; db["user3"]= "pqr"; if(db.[user] == passwdGiven) { // allow to login } else { // dont allow to login }

129

Friends and Members


Better choice? Motivation
Minimize the number of functions accessing representation of a class directly Only one choice for constructors, destructors, virtual functions

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

Friends and Members


class X { // X(int); int m1(); int m2() const; friend void f1(X&); friend void f2(const X&); friend void f3(X); }; void h() { f1(99); //error: f1(X(99)) not tried f2(99); //ok: f2(X(99)); f3(99); //ok: f3(X(99)); } void g() { 99.m1(); 99.m2(); } //error: X(99).m1() not tried //error: X(99).m2() not tried

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

Friends and Members


If no type conversion is desired, there is no compelling reason to choose a member or non-member Choices depends on function call syntax inv(m) or m.inv()? If inv() really inverts m, choose member otherwise nonmember Member call syntax makes it clear to the user that object may be modified; a reference argument is far less obvious Members are shorter than non-member

U.K.R., 2008

OOP

132

Operators for large objects


class Matrix { double m[4][4]; Matrix(int); friend Matrix operator+(const Matrix&, const Matrix&); }; Matrix operator+(const Matrix& m1, const Matrix& m2) { Matrix temp; for(int i=0;i<4;i++) for(int j=0;j<4;j++) temp.m[i][j] = m1.m[i][j]+m2[i]j]; return temp; }

U.K.R., 2008

OOP

133

Operators for large objects


const int MAX 10; Matrix & get_matrix() { static int index = 0; static Matrix buf[MAX]; return buf[index++]; } Matrix operator+(const Matrix& m1, const Matrix& m2) { Matrix& temp = get_matrix(); for(int i=0;i<4;i++) for(int j=0;j<4;j++) temp.m[i][j] = m1.m[i][j]+m2[i]j]; return temp; }

U.K.R., 2008

OOP

134

Overloading << operator


#include <iostream.h> int main() { char *str = C++; int x = 2; cout << str; cout << x; return 1; }

//cout.operator<<(str); cout.operator<<(x);

Consider the simplified version of string I/O from standard library


class ostream { ostream& operator<<(const char*); ostream& operator<<(int); /**/ }; extern ostream cout;
U.K.R., 2008 OOP 135

Overloading << operator


#include <iostream.h> int main() { Array a(10), b(3), c(5); String str(C++); Table matrix(3, 4); cout << a; //operator<<(cout, a); cout << str; //operator<<(cout, str); cout << matrix; //operator<<(cout, matrix); cout << b << c; //operator << (operator << (cout, b), c) return 1; }

U.K.R., 2008

OOP

136

<< operator implementation


class Array { /**/ friend ostream& operator<<(ostream& os, const Array&); }; ostream& operator<<(ostream& os, const Array&); ostream& operator<<(ostream& os, const Array& a) { for(int i=0;i<a.length;i++) os << a[i] << ' '; return os; }

U.K.R., 2008

OOP

137

<< operator implementation


class String { /**/ friend ostream& operator<<(ostream& os, const String&); }; ostream& operator<<(ostream& os, const String&);

ostream& operator<<(ostream& os, const String& s) { os << s.buf; return os; }

U.K.R., 2008

OOP

138

<< operator implementation


class Table { /**/ friend ostream& operator<<(ostream& os, const Table&); }; ostream& operator<<(ostream& os, const Table&); ostream& operator<<(ostream& os, const Table& t) { for(int i=0;i<t.row;i++) { os << "\n"; os << t[i]; } return os; }

U.K.R., 2008

OOP

139

Overloading >> operator


#include <iostream.h> int main() { char str[10]; int x ; cin >> str; cin >> x; return 1; }

//cin.operator>>(str); cin.operator>>(x);

Consider the simplified version of string I/O from standard library


class istream { istream& operator>>(const char*); istream& operator>>(int); /**/ }; extern istream cin;
U.K.R., 2008 OOP 140

Overloading >> operator


#include <iostream.h> int main() { Array a , b, c; String str; Table matrix; cin >> a; //operator>>(cin, a); cin >> str; //operator>>(cin, str); cin >> matrix; //operator>>(cin, matrix); cin >> b << c; //operator >> (operator >> (cin, b), c); return 1; }

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 from char * to String

//conversion from Table to Matrix

Convenient but has implication that can be undesirable


U.K.R., 2008 OOP 142

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

User defined conversions are considered when necessary


class String { char *buf; public: String(char *); operator char*(); }; void f() { String str(C++); char *s = str; str = Java; }
U.K.R., 2008

//conversion to char *

//s = char*(str); //in = String(2);


OOP 143

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 to int //conversion to Integer

//x = int(in), x = 4 //y = int(in) + int(out), y = 14 //in = Index(2) //i = Integer(in);


OOP 144

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

Conversion operator Implementation


Index::operator int() { return i; } Index::operator Integer() { return Integer(i); } String::operator char*() { char *str = new char[length+1]; strcpy(str, buf); return str; }

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 }

Programmer should specify the precision to be used

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

Overloading new operator


int *x = new int; float *f = new float; double *d = new double; // *x = ? // *f = ? // *d = ?

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

// operator new(sizeof(int)); // operator new(sizeof(float)); // operator new(sizeof(double));


OOP 153

new operator implementation


void * operator new (size_t sz) { void * temp = malloc(sz); for(int i = 0; i < sz; i++) ((char *)temp)[i] = 0; return temp; }

U.K.R., 2008

OOP

154

new operator for class


Point *p = new Point;

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

new operator for class


Implementation
void * Point::operator new (size_t sz) { void * temp = malloc(sz); if(temp == NULL) { //try to find some free memory void * temp = malloc(sz); if(temp == NULL) { cout << "Memory exhausted\n"; return NULL; } } return temp; }

U.K.R., 2008

OOP

156

Overloading new[ ] operator


Default behavior can be overridden by redefining new operator
int *x = new int[2]; float *f = new float[4]; double *d = new double[10]; // x[0], x[1] = ? // f[2] = ? // d[4] = ?

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

new[ ] operator implementation


void * operator new[ ] (size_t sz) { void * temp = malloc(sz); for(int i = 0; i < sz; i++) ((char *)temp)[i] = 0; return temp; }

U.K.R., 2008

OOP

158

Overloading delete operator


Deallocates memory allocated by new

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

//object used as a function


OOP 161

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->(); };

p1(5,6); PPtr pp(p1); cout << pp->getx();


U.K.R., 2008 OOP 163

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

Bitwise operator overloading


class Bit { char b:1; public: Bit(); Bit(int); Bit operator|(Bit); Bit operator&(Bit); Bit operator^(Bit); Bit& operator!(); }; Bit Bit::operator|(Bit bit) { Bit temp; temp.b = b|bit.b; return temp; }

Bit b1(1), b2(0), b3; b3 = b1 | b2; b3 = b1 & b2; b3 = b1 ^ b2; b3 = !b1;

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

Student Reg.No. Course Marks

Teaching Staff Edn.Qual. Designation Specialization

Person is a generalization of Student. Student is a specialization of Person.


U.K.R., 2008 OOP 167

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

Defining Derived Class


The general form of deriving a subclass from a base class is as follows
class derived-class-name : visibility-mode base-class-name { // .// members of the derived class };

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

Simple or Single Inheritance


This a process in which a sub class is derived from only one superclass. a Class Student is derived from a Class Person
superclass(base class) Person

class Person { /* */ }; class Student : public Person { /**/ };

Student

subclass(derived class) visibility mode


U.K.R., 2008 OOP 171

Multilevel or Varied Inheritance


The method of deriving a class from another derived class is known as Multiple or Varied Inheritance. A derived class CS-Student is derived from another derived class Student.
Person class Person { /**/ }; class Student : public Person { /**/ }; class CS -Student : public Student { /**/ };
OOP 172

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

Access Specifiers with Inheritance

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

Access Specifiers with Inheritance


class X { int priv; protected: int prot; public: int publ; void m( ); }; void X::m( ) { priv =1; //Ok prot =1; //Ok publ =1; //Ok } class Y : public X { void mderived( ); };
U.K.R., 2008

Y::mderived( ) { priv =1; prot = 2; publ = 3;

//Error priv is private and //cannot be inherited // Ok // 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; // Ok }

OOP

180

Public, Protected and Private derivation

Class A
private : int a1;

Class B
private : int b1;

Class B: Public A
private : int b1;

protected : int a2;

protected : int b2;

protected: int a2; int b2 public: int b3; int a3;

public : int a3;

public : int b3;

Public Derivation
U.K.R., 2008 OOP 181

Public derivation - example


class X { int priv; protected: int prot; public: int publ; void m( ); }; void X::m( ) { priv =1; //Ok prot =1; //Ok publ =1; //Ok } class Y : public X { void mderived( ); };
U.K.R., 2008

Y::mderived( ) { priv =1; prot =2; publ=3;

//Error priv is private and //cannot be inherited // Ok // 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; // Ok }

OOP

182

Protected derivation - example


The inherited public and protected members of a base class become protected members of the derived class
Class A
private : int a1; protected : int a2; public : int a3;

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

Protected derivation - example


class X { int priv; protected: int prot; public: int publ; void m( ); }; void X::m( ) { priv =1; //Ok prot =1; //Ok publ =1; //Ok } class Y : protected X { void mderived( ); };
U.K.R., 2008

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

Private derivation - example


The inherited public and protected members of a private derivation become private members of the derived class.
Class A
private : int a1; protected : int a2; public : int a3;

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

Private derivation - example


Class X { int priv; protected: int prot; public: int publ; void m( ); }; void X::m( ) { priv =1; //Ok prot =1; //Ok publ =1; //Ok } class Y : private X { void mderived( ); }; Y::mderived( ) { priv =1; //Error priv is private and //cannot be inherited prot =2; // Ok publ=3; // Ok U.K.R., 2008 }

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

Derived Class Constructors


A base class constructor is invoked, when a derived class object is created. If base class does not have default constructor, derived class constructor has to invoke base class constructor explicitly. Constructor of the base class will invoked before constructor of derived class

U.K.R., 2008

OOP

187

Derived Class Constructors


class B { int x; public : B( ) { cout << B::B( ) Fires << endl; } }; class D : public B { int y; public : D( ) { cout << D::D( ) Fires << endl; } }; void main( ) { D d; }
U.K.R., 2008 OOP

B::B( ) Fires D::D( ) Fires

188

Derived Class Constructors


class B { int a; public : B( ) { a = 0; cout<<B::B( ) Fires<<endl;} B(int x) { a =x; cout<<B::B(int) Fires<<endl; } }; class D : public B { int b; public : D( ) { b =0; cout<<D::D( ) Fires<<endl;} D(int x) { b =x; cout<<D::D(int) Fires<<endl;} D(int x, int y) : B(y) { b =x; cout<<D::D(int, int) Fires<<endl; } }; void main( ) { D d; D d(10); D d(10, 20); }
U.K.R., 2008 OOP

B::B( ) Fires D::D( ) Fires B::B( ) Fires D::D(int) Fires B::B(int) Fires D::D(int, int) Fires

189

Derived Class Destructors


Derived class destructors are called before base class destructors.
class B { int x; public : B( ) { cout<<B Constructor Invoked<<endl;} ~B( ) { cout<<B Destructor Invoked <<endl;} }; class D : public B { int y; public : D( ) { cout<<D Constructor Invoked <<endl;} ~ D( ) { cout<<D Destructor Invoked<<endl;} }; void main( ) { D d; }

B Constructor Invoked D Constructor Invoked D Destructor Invoked B Destructor Invoked

U.K.R., 2008

OOP

190

Overriding Member Functions


In the derived class, function inherited from base class, need to be redefined sometimes. When the same function exists in both the base class and the derived class, the function in the derived class is executed on derived class object
void main( ) { Employee e(John); Manager m(Mike,1); e.printDetails(); //Employee::printDetails invoked m.printDetails(); //Employee::printDetails invoked }

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

m.printDetails(); //Manager::printDetails invoked

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

Prototype (Declaration): template <class Type> Type abs(Type val);

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

Function Template Overloading


Other function templates with same name
Different parameters
template<class T> T sqrt(T); template<class T> complex<T> sqrt(complex<T>); double sqrt(double);

Non-template functions with same name


Different function arguments

Compiler performs matching process


Tries to find precise match of function name and argument types If fails, function template generates function-template specialization and uses most specialized one
complex<double> z; sqrt(1); //sqrt<int>(int) sqrt(2.0); //sqrt(double) sqrt(z); //sqrt<double>(complex<double>) //sqrt<double>(complex<double>) is more specilized than sqrt<complex<T>>(complex<double>) template<class T> class complex { T real, img; /**/ };

U.K.R., 2008

OOP

201

Template Function Specialization


By default a template gives a single definition to be used for every template argumentdoes not make sense always
template <class T> bool less(T a, T b) { return a<b?true:false; } less(2,5); less(3.4, 1.5); less(C++, Java);

Fails to compare two strings


template<> bool less<const char*>(const char *a, const char *b) { return strcmp(a,b); }

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

Template Function Specialization


Another example
class Stack { int size, top, *a; Stack operator=(const Stack&); /**/ } Stack s1(1000), s2(2000); swap(s1, s2); //inefficient template<class T> void swap(T &a, T &b) { T temp = a; a = b; b = temp; }

void Stack:::swap(Stack &s) { swap(size, s.size); swap(top, s.top); swap(a, s.a); }

//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

Another Example main( ) { String lang(C++); char *str=lang;


U.K.R., 2008

//char * to String conversion //String to char* conversion


OOP 204

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

Basic class Class basic Class class


U.K.R., 2008

Not applicable Casting Operator Casting operator


OOP

Constructor Not Applicable Constructor


205

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

//Index to int conversion operator

//int to index conversion //x=int(i) //i=Index(x)

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

Ambiguity During Type Conversion


#include <string.h> class String { public: String( char *s ); operator char *(); private: char _text[80]; }; bool operator==(String , String ) ; The compiler has two choices and no way of determining which is correct. (i)It can convert ch to an object of type String using the constructor and then perform the comparison using the user-defined operator==. (ii)It can convert s to a pointer of type char * using the conversion function and then perform a comparison of the pointers.

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

Ambiguity During Type Conversion


class Index { int x; public : Index(int i):x(i){} operator int() { //Index to int conversion operator return x; } }; int operator +(Index, Index); main( ) { Index i(3); int x; x+i; //ambiguity, operator(Index(x), i) or x+int(i) ? }
U.K.R., 2008 OOP 209

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

Constructors in Composite Class


class X { int i; public: X(int ii=0):i(ii) { cout << Xs constructor; }; }; class Y { int j; public: Y(int jj=0):j(jj) { cout << Ys constructor; }; }; class Z { int k; public: Y y; X x; Z(int a, int b, int c) : x(a), y(b), k(c) { cout << Zs constructor; } int main() { Z z(1,2,3); } Output : Ys constructor Xs constructor Zs constructor
OOP 211

U.K.R., 2008

Polymorphism : NonVirtual Functions


Base class Pointer can point an object of its subclass Base class reference can refer an object of its subclass
class B{ public: void f(); }; class D: public B{ public: // f() not overridden }; void main(){ D d; D*pb = &d; //obvious B*pd = &d; //obvious d.f(); // B::f(), call f() through d pd->f(); // B::f(), call f() through a derived class pointer pb->f(); //B::f(), call f() through a base class pointer }
U.K.R., 2008 OOP

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

Polymorphism : NonVirtual Functions

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

Polymorphism : NonVirtual Functions

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

Polymorphism : Virtual functions


Virtual Functions
A member function that is declared as virtual in a base class and redefined by a derived class. A virtual function defines a general class of actions . The redefined virtual function implements a specific method. For non-virtual functions with the same name, the system determines at compile time which of the function to invoke. For virtual methods with the same name the system determines at run time which of the methods to invoke.
U.K.R., 2008 OOP 215

Virtual Functions : Example 1


Class B { public: virtual void g(); int h(); }; class D : public B { public: void g(); int h(); }; int main() { D d; B *ptr = &d; ptr->h(); B::h invoked ptr->g(); D::h invoked }

U.K.R., 2008

OOP

216

Virtual Functions : Example 2


class Base { public: virtual void fun() {cout<<This is base fun().\n; } }; class Derived0 : public Base { public: void fun() {cout<< This is derived0 fun().\n;} }; class Derived1 : public Base { public: void fun() { cout<< This is derived1 fun() .\n; } };
Output This is base fun() This is derive0 fun() This is derive1 fun()
U.K.R., 2008 OOP

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 : Constructors

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

Virtual Functions : Constructors contd


class B { public: B( ) { this->f(); } virtual void f() { cout<<Executing B::f()<<endln; } };

main() { D d; cout<<object d was created successfully<<endl; d.f(); }

class D: public B { public: D( ){ } virtual void f( ) { cout<<Executing D::f()<<endl; } };

output
Executing B::f() object d was created successfully. Executing D::f()

U.K.R., 2008

OOP

219

Virtual Functions : Destructors


class B { char * ptrB; public: B() { ptrB = new char[5]; cout<<B allocates 5 bytes\n; } ~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

220

Virtual Functions : Destructors contd


void main() { while(1) f(); } void f() { B*p=new D; delete p; } The Memory will be exhausted, in each call of function f( ), B allocates 5 bytes D allocates 1000 bytes B frees 5 bytes.

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

Virtual Function : Default Arguments


The default argument 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.
class Base { public: virtual int foo(int ival=1024){ cout<<base::foo()ival :<<ival <<endl; return ival; } }; class Derived :: public Base{ public: virtual int foo(int ival=2048) { cout<<derived::foo() ival : << ival << endl; return ival; } };
U.K.R., 2008 OOP 223

Virtual Function : Default Arguments contd


int main () { Derived *pd=new derived; Base *pb=pd; int val = pb->foo(); cout<<main : val through base <<val<<endl; val = pd->foo(); cout<<main : val through derived <<val<<endl; } Output
derived:: foo() ival : 1024 main : val through base : 1024 derived :: foo() ival : 2048 main : val through derived : 2048

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

Abstract Class & Pure Virtual Functions


Abstract Class A class that serves only as a base class from which other classes can be derived ; no instance of an abstract base class are ever created. If a base class declares a pure virtual functions , no instance of the class can be created, and so it is necessarily an abstract base class. Pure Virtual Functions A virtual function that is declared in a base but not defined there ; responsibility for defining the function falls on the derived classes, each of which generally provides a different definition.

U.K.R., 2008

OOP

225

Pure Virtual Function


class Base { public: virtual void show()=0; // Pure Virtual function }; class Derv1 : public Base { public: void show(){ cout<<\n Derv 1; } }; class Derv2 : public Base{ public: void show(){cout<<\n In Derv2; } }; void main(){ Base *List[2]; Derv1 dv1; Derv2 dv2; List[0]=&dv1; List[1]=&dv2; List[0]->show(); List[1]->show(); }
OOP 226

U.K.R., 2008

Pure Virtual Function


class Shape { public: virtual void draw()=0; // Pure Virtual function }; class Shape2D : public Shape { public: virtual float area()=0; // Pure Virtual function }; class Circle : public Shape2D { public: void draw(); float area(); // concrete functions };
U.K.R., 2008 OOP

class Shape3D : public Shape { public: virtual float volume(); // Pure Virtual function }; class Cube : public Shape3D { public: void draw(); float volume(); // concrete functions };

227

Virtual Function & Private/Protected Derivation


Polymorphism does not work with private or protected derivation
class Base{ public: virtual void f(); }; class Derived : private Base{ public: void f(); }; Base *ptr, b; Derived d; ptr=&d; // illegal ptr=&b; // ok ptr->f(); // calls B::f()
U.K.R., 2008

Standard conversions dont convert derived class pointers to base class pointers with private/protected derivation. Always use public inheritance with polymorphism.

OOP

228

Virtual Function Implementation


Most compiler build a virtual function table for each polymorphic class. All object of the same class share the same virtual function table(vtable). The vtable is an array of pointers to virtual functions that have definitions in either a base class or a derived class . The value of the pointer depends on whether or not the derives class override a base class virtual function with a new version of its own. A polymorphic class with at least one virtual function includes a hidden pointer (vptr) to its object which points to vtable.
U.K.R., 2008 OOP 229

Virtual Function Implementation


contd
Base vtbl;
Base::f1()

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

Virtual Function Example 4


class Base{ public : Base() { } virtual void f1() { cout<<base::f1( ) << endl; } virtual void f2( ) { cout << Base:: f2()<<endl; } virtual void f3() { cout<<Base :: f3()<<endl; } }; class Derived { public: Derived() { } void f2() { cout<<Derived ::f2()<<endl; } virtual void f4() { cout<<Derived ::f4()<,endl;} };
U.K.R., 2008 OOP

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

Object Oriented Programming: Next Step


ll Book Book PDF URL Description OO A & D by Grady Booch Object oriented software concepts by Bertrand Mayer http://www.kbcafe.com/articles/OOP. Concepts.pdf Reference Topic or Module All All All

http://www.desy.de/gna/html/cc/Tutor All ial/tutorial.html http://www.bitpipe.com/rlist/term/Obj ect-Oriented-Programming.html All

http://www.well.com/user/ritchie/oo.h All tml http://www.planetpdf.com/codecuts/p All dfs/ooc.pdf


U.K.R., 2008 OOP 232

Congratulations! You have successfully completed

Object Oriented Programming

U.K.R., 2008

OOP

233

Das könnte Ihnen auch gefallen