OOP - Lecture 6 Classes
OOP - Lecture 6 Classes
Spring 2022
Hira Naveed
Lecture # 6 Classes
Procedural Programming
displayWidth();
displayLength(); Functions
displayArea();
Limitations of Procedural Programming
double width;
Data
double length;
Rectangle
displayWidth();
Object
displayLength(); Functions
displayArea();
Some Examples of Objects
• Attributes:
• on (true/false)
• Behavior
Car
• Switch on • Attributes:
• Switch off
• Gas in tank
• Check if on
Light Bulb • Mileage
• Behavior
• Attributes:
• Accelerate
• balance
• Brake
• Behavior
• Load fuel
• Deposit • Check fuel
• Withdraw
Bank Account • Check balance
Objects Interact with Each Other
Get Loan
Bank Customer
Bank Account
Object-Oriented Programming
Terminology
• Class: an abstract data-type or a user-defined data type,
similar to a struct (allows bundling of related variables)
{
double width;
Data (attributes)
double length;
displayWidth();
displayLength(); Functions
displayArea();
};
width = 2
length = 5
width = 4
width = 4 length = 3
length = 2
Defining an Instance of a Class
Rectangle r;
double length;
public:
void displayWidth(); Public Members
void displayLength();
void displayArea();
};
More on Access Specifiers
struct Rectangle
Members of a class
{ are
double width; private by default
double length;
} r1;
class Rectangle
{
double width;
double length;
};
Rectangle r1; //class object
cout << r1.width; //ERROR, width is private
Access Specifiers
class Rectangle {
private:
double width; Access any public
members
double length; of the class using the dot
public: operator:
r1.displayArea(
double getWidth(){ )
return width; }
};
Rectangle r1; //class object r1
cout << r1.getWidth(); //works getWidth()
is public
Defining a Member Functions
class Rectangle {
private:
double width;
double length;
public:
double calcArea() {
return width * length; //inline func
}
};
Defining a Member Functions
returnType ClassName::MemberFunctionName( ){
…………
}
• Different classes can have member functions with the
same name
Defining a Member Functions
class Rectangle {
private:
double width;
double length;
public:
double calcArea(); //prototype
}; //class declaration ends
double Rectangle::calcArea()
{ return width * length; //out-of-line func
}
Defining a Member Functions
Whether member
function is inline or out-
class Rectangle { of-line
private: Access remains the
same as declared in
double width; the class
double length;
public:
double calcArea(); //prototype
}; //class declaration ends
double Rectangle::calcArea()
{ return width * length; }
Private Member Functions
• Private Member Functions:
• Only accessible (callable) from member functions of
the class
class Rectangle {
private: private member function
(out-of-line)
double width;
double length;
double calcArea();
public:
void displayArea(){ cout<<
calcArea();}
};
double Rectangle::calcArea(){
return length * width;
Using Private Member Functions
class Rectangle {
private: private member function
(inline)
double width;
double length;
double calcArea(){
return length * width;
}
public:
void displayArea(){ cout<<
calcArea();}
};
Setters and Getters
class Rectangle
{
private:
double width;
public:
void changeWidth() const {
width++; //ERROR }
};
Getters do not change an object's data,
so they should be marked const.
class Rectangle
{
private:
double width;
double length;
public:
void setWidth(double);
void setLength(double);
38
Reference and Pointers to Objects
Separating Specification from
Implementation
• Makes it easier to modify programs
6 #ifndef TIME1_H
7 #define TIME1_H
If time1.h (TIME1_H) is not defined (#ifndef)
8 then it is loaded (#define TIME1_H). If TIME1_H
9 // Time abstract data type definition is already defined, then everything up to #endif is
ignored.
10 class Time { This prevents loading a header file multiple times.
11 public:
12 Time(); // constructor
13 void setTime( int, int, int ); // set hour, minute, second
14 void printMilitary(); // print military time format
15 void printStandard(); // print standard time format
16 private:
17 int hour; // 0 - 23
18 int minute; // 0 - 59
19 int second; // 0 - 59
20 };
21
22 #endif
23 // Fig. 6.5: time1.cpp
24 // Member function definitions for Time class.
25 #include <iostream>
26
27 using std::cout;
28 Source file uses #include to load the
29 #include "time1.h" header file
30
31 // Time constructor initializes each data member to zero.
32 // Ensures all Time objects start in a consistent state.
33 Time::Time() { hour = minute = second = 0; }
34
35 // Set a new Time value using military time. Perform validity
36 // checks on the data values. Set invalid values to zero.
37 void Time::setTime( int h, int m, int s )
38 {
39 hour = ( h >= 0 && h < 24 ) ? h : 0;
40 minute = ( m >= 0 && m < 60 ) ? m : 0;
41 second = ( s >= 0 && s < 60 ) ? s : 0; Source file contains
42 } function definitions
43
44 // Print Time in military format
45 void Time::printMilitary()
46 {
47 cout << ( hour < 10 ? "0" : "" ) << hour << ":"
48 << ( minute < 10 ? "0" : "" ) << minute;
49 }
50
51 // Print time in standard format
52 void Time::printStandard()
53 {
54 cout << ( ( hour == 0 || hour == 12 ) ? 12 : hour % 12 )
55 << ":" << ( minute < 10 ? "0" : "" ) << minute
56 << ":" << ( second < 10 ? "0" : "" ) << second
57 << ( hour < 12 ? " AM" : " PM" );
58 }
Constructors
class Demo
{
public:
Demo(); // Constructor
};
Demo::Demo() //out-of-line
{
cout << "Welcome to the constructor!\n";
}
Constructors
class Demo
{
public:
Demo(){ //inline function
// Constructor
cout << "Welcome to the constructor!\n";
}
};
Constructors
//Prints
Welcome to the constructor!
Constructors
What Constructors Do
Rectangle(double, double);
Rectangle r;
Rectangle r;
Rectangle r1(10.0);
Rectangle r2(10.0, 2.0);
(continued)
Constructors, Destructors, and
Dynamically Allocated Objects
• When an object is dynamically allocated with the new
operator, its constructor executes:
delete r;
Only One Default Constructor
and One Destructor
• Do not provide more than one default constructor for a
class: one that takes no arguments and one that has
default arguments for all parameters
Square();
Square(int = 0); // will not compile
24
25 CreateAndDestroy::CreateAndDestroy( int value )
26 { Constructor and Destructor
changed to print when they are
27 data = value; called.
28 cout << "Object " << data << " constructor";
29 }
30
31 CreateAndDestroy::~CreateAndDestroy()
32 { cout << "Object " << data << " destructor " << endl; }
63
64 // Function to create objects
65 void create( void )
66 {
67 CreateAndDestroy fifth( 5 );
68 cout << " (local in create)" << endl;
69
70
71
72
42 73 CreateAndDestroy seventh( 7 );
43 void create( void ); // prototype 74 cout << " (local in create)" << endl;
44 75 }
45 CreateAndDestroy first( 1 ); // global object
46
47 int main()
48 {
49 cout << " (global created before main)" << endl;
50
51 CreateAndDestroy second( 2 ); // local object
52 cout << " (local in main)" << endl;
53
54
55
56
57 create(); // call function to create objects
58
59 CreateAndDestroy fourth( 4 ); // local object
60 cout << " (local in main)" << endl;
61 return 0;
62 }
OUTPUT
Object 1 constructor (global created before main)
Object 2 constructor (local in main)
Object 5 constructor (local in create)
Object 7 constructor (local in create)
Object 7 destructor
Object 5 destructor
Object 4 constructor (local in main) Notice how the order of the
Object 4 destructor constructor and destructor call
Object 2 destructor
Object 1 destructor
depends on the types of variables
(local and global) they are
associated with.
Destructor Example
void f1()
{
Employee *c = new Employee[3];
c[0].var1 = 322;
c[1].var1 = 5
c[2].var1 = 9;lete [] c; //destructor
will call here
}
class Item {
private:
double cost;
int units;
public:
Item() { //Default Constructor
cost = 0.0;
units = 0; }
Item inventory[40];
Item inventory[3] =
{ 22.4, 10.30, 99.0 };
inventory[2].setUnits(30);
Date *dates[31];
Rectangle box2;
box2 = box1;
box2 box1
Rectangle box2;
box2 = box1;
Date::Date(Date &date)
{
month = date.month;
day = date.day;
year = date.year;
}
Uses of the Copy Constructor
return 0; }
int main(){ s1
s2’s default copy
Student s1;
constructor is called
and s1’s member
char name1[]="Bruce Wayne"; name
variable values are
s1.setName(name1);
copied in s2 Dynamically
allocated array
cout<<s1.getName()<<endl;
B r u c e W a y n e
Student s2 = s1;
name
s2
Output
Bruce Wayne
return 0; }
int main(){ s1
Student s1;Pointers in both
objects will point to
char name1[]="Bruce
the same addressWayne"; name
a.k.a shallow copy
s1.setName(name1); Dynamically
allocated array
cout<<s1.getName()<<endl;
B r u c e W a y n e
Student s2 = s1;
cout<<s2.getName()<<endl;
name
s2
Output
Bruce Wayne
return 0; }
int main(){ s1
Student s1;
char name1[]="Bruce Wayne"; name
s1.setName(name1); Dynamically
allocated array
cout<<s1.getName()<<endl;
B r u c e W a y n e
Student s2 = s1;
cout<<s2.getName()<<endl;
name
s2
Output
Bruce Wayne
Bruce Wayne
return 0; }
int main(){ s1
Student s1;
char name1[]="Bruce Wayne"; name
s1.setName(name1); Dynamically
allocated array
cout<<s1.getName()<<endl;
B r u c e W a y n e
Student s2 = s1;
cout<<s2.getName()<<endl;
name
Bruce Wayne
Bruce Wayne
return 0; }
int main(){ s1
Student s1;
char name1[]="Bruce Wayne"; name
s1.setName(name1); Dynamically
allocated array
cout<<s1.getName()<<endl;
C l a r k K e n n t
Student s2 = s1;
cout<<s2.getName()<<endl;
name
Bruce Wayne
Bruce Wayne
return 0; }
int main(){ s1
Student s1;
char name1[]="Bruce Wayne"; name
s1.setName(name1); Dynamically
allocated array
cout<<s1.getName()<<endl;
C l a r k K e n n t
Student s2 = s1;
cout<<s2.getName()<<endl;
name
Bruce Wayne
Bruce Wayne
Clark Kennt
return 0; }
int main(){ s1
Student s1;
char name1[]="Bruce Wayne"; name
s1.setName(name1); Dynamically
allocated array
cout<<s1.getName()<<endl;
C l a r k K e n n t
Student s2 = s1;
cout<<s2.getName()<<endl;
name
Student s2 = s1;
cout<<s2.getName()<<endl;
name
Student s2 = s1;
cout<<s2.getName()<<endl; B r u c e W a y n e
Output
s2 Bruce Wayne
Bruce Wayne
return 0; }
int main(){ s1
Student s1;
char name1[]="Bruce Wayne"; name
s1.setName(name1); Dynamically
allocated array
cout<<s1.getName()<<endl;
B r u c e W a y n e
Student s2 = s1;
cout<<s2.getName()<<endl; C l a r k K e n n t
fuel=0;
model=“”;
car1
class Car { Car car1,car2,car3;
int fuel;
string model;
static int totalCars;
public:
Car() { //constructor
fuel = 0;
model = “”;
totalCars++; }
}; totalCars = 1
int Car::totalCars; (static)
fuel=0;
model=“”;
car1
class Car { Car car1,car2,car3;
int fuel;
string model;
static int totalCars;
public:
Car() { //constructor
fuel = 0;
model = “”;
totalCars++; }
}; totalCars = 1
int Car::totalCars; (static)
fuel=0; fuel=0;
model=“”; model=“”;
car1 car2
class Car { Car car1,car2,car3;
int fuel;
string model;
static int totalCars;
public:
Car() { //constructor
fuel = 0;
model = “”;
totalCars++; }
}; totalCars = 2
int Car::totalCars; (static)
fuel=0; fuel=0;
model=“”; model=“”;
car1 car2
class Car { Car car1,car2,car3;
int fuel;
string model;
static int totalCars;
public:
Car() { //constructor
fuel = 0;
model = “”;
totalCars++; }
}; totalCars = 2
int Car::totalCars; (static)
• Static Variables
• Default Initialization: 0 or Null (for pointers)
• Initialization: user defined value
• Initialization is made just once, at compile time.
• Accessibility: Private or Public
Public static Member Variables
• Non-static function:
• Can access: all class members
• Static functions:
• Can access: static data and static functions
• Cannot access: non-static data, non-static functions,
and this pointer
Public static Member Functions
122
123 return 0;
count back to zero.
124 }
this->fuel = fuel;
}
this Pointer
void setFuel(int fuel, Car* const this) {
this->fuel = fuel;
}
//Parametrized Constructor
Car(int fuel, string model) {
this->fuel = fuel;
this->model = model;
}
Using the this Pointer
• Function returns a reference pointer to the same object
{ return *this; }
128
129 return 0;
130 }
public:
//inline with initializer list
Test() : marks(0),total(0) {} //default constructor
int getMarks() {
return marks;
}
int getTotal() {
return total;
}
};
Member Initializer List
class Test {
int marks;
int total;
public:
//inline with initializer list
Test() : marks(0),total(0) {} //default constructor
int getMarks() {
return marks;
}
int getTotal() {
return total;
}
};
Member Initializer List
class Test {
int marks;
int total;
public:
Test(); //prototype
Test(int, int ); //prototype
int getMarks() {
return marks;
}
int getTotal() {
return total;
}
};
//out of line with initializer list
Test::Test() :marks(0), total(0) {}
Test::Test(int m,int t): marks(m), total(t) {}
Member Initializer List (Non-const
Members)
When to use Member Initializer List
• Read-only objects
• Properties of friendship
• Friendship is granted, not taken
• Not symmetric (if B a friend of A, A not necessarily
a friend of B)
• Not transitive (if A a friend of B, B a friend of C, A
not necessarily a friend of C)
1 // Fig. 7.5: fig07_05.cpp
2 // Friends can access private members of a class.
3 #include <iostream> setA a friend of class Count
4 (can access private data).
5 using std::cout;
6 using std::endl;
7
8 // Modified Count class
9 class Count {
10 friend void setA( Count &, int ); // friend function declaration
11 public:
12 Count() { a = 0; } // constructor
13 void print() const { cout << x << endl; } // output
14 private:
15 int a; // data member
16 }; setA is defined normally and is
17 not a member function of
18 // Can modify private data of Count because Count.
19 // setX is declared as a friend function of Count
20 void setA( Count &c, int val ) Changing private variables allowed.
21 {
22 c.x = val; // legal: setX is a friend of Count
23 }
24
25 int main()
26 {
27 Count counter;
28
29 cout << "counter.a after instantiation: ";
30 counter.print();
31 cout << "counter.a after call to setA friend
function: ";
32 setA( counter, 8 ); // set a with a friend
33 counter.print();
34 return 0;
35 }