0% found this document useful (0 votes)
3 views

5-Introduction to Classes-1

The document provides an introduction to Object-Oriented Programming (OOP) concepts, focusing on classes and objects. It explains the structure of classes, including data fields, member functions, constructors, and access modifiers, as well as the importance of data hiding and encapsulation. Additionally, it includes examples in C++ to illustrate the implementation of these concepts.
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
3 views

5-Introduction to Classes-1

The document provides an introduction to Object-Oriented Programming (OOP) concepts, focusing on classes and objects. It explains the structure of classes, including data fields, member functions, constructors, and access modifiers, as well as the importance of data hiding and encapsulation. Additionally, it includes examples in C++ to illustrate the implementation of these concepts.
Copyright
© © All Rights Reserved
Available Formats
Download as PPTX, PDF, TXT or read online on Scribd
You are on page 1/ 110

Introduction to Classes

(COMP-112)

Dr. Abdul Waheed Khan

Department of IT & Computer Science


PAF-IAST
Why Objects?
But binary is hard (for humans) to work
with…
Procedural VS. Object-Oriented Programming
Object-oriented Programming (OOP)
• Object-oriented programming approach organizes
programs in a way that mirrors the real world, in
which all objects are associated with both attributes
and behaviors

• Object-oriented programming involves thinking in


terms of objects

• An OOP program can be viewed as a collection of


cooperating objects
Classes
Classes in OOP
 Classes are constructs/templates that define
objects of the same type.

 A class uses Variables (data fields) to define state

 A class uses Functions to define behaviors.

 Additionally, a class provides a special type of


function, known as constructors:
 Invoked to construct objects from the class.
Objects in OOP
 An object has a unique identity, state, and behaviors.

 The state of an object consists of a set of data fields


(also known as properties) with their current values.

 The behavior of an object is defined by a set of


functions.
UML Diagram for Class and Object
Circle Class name

radius: double Data fields

Circle() Constructors and Methods


Circle(newRadius: double)
getArea(): double

circle1: Circle circle2: Circle circle3: Circle

radius: 10 radius: 25 radius: 125


Class in C++ - Example
Class in C++ - Example
class Circle
{
public:
Note:
// The radius of this circle
double radius; Data field the special syntax
for constructor
// Construct a circle object
Circle() (no return type!)
{
radius = 1;
Constructors
}

// Construct a circle object


Circle(double newRadius)
{
radius = newRadius;
}

// Return the area of this circle


double getArea() Function
{
return radius * radius * 3.14159;
}
};
Class is a Type
• You can use primitive data types to define variables.

• You can also use class names to declare object names.

• In this sense, a class is an abstract data-type or user-


defined data type.
Class Data Members and Member Functions
• The data items within a class are called
data members or data fields or instance
variables

• Member functions are functions that are


included within a class. Also known as
instance functions.
Object Creation - Instantiation
• In C++, you can assign a name when creating an object.

• A constructor is invoked when an object is created.

• The syntax to create an object using the no-arg


constructor is:

ClassName objectName;

• Defining objects in this way means creating them. This is


also called instantiating them.
Object Member Access Operator
• After object creation, its data and functions can be
accessed (invoked) using:
• The . operator, also known as the object member access
operator.

• objectName.dataField references a data field in the object

• objectName.function( ) invokes a function on the object


A Simple Program – Object Creation
class Circle
{ C1 Object Instance
private:
double radius;

public: : C1
Circle()
radius: 5.0
{ radius = 5.0; }
double getArea( )
{ return radius * radius * 3.14159; } Allocate memory
}; for radius

void main()
{
Circle C1;
//C1.radius = 10; can’t access private member outside the class
cout<<“Area of circle = “<<C1.getArea( );
}
Local Classes
• Local classes: A local class is declared within a function
definition.

• A local class cannot have static data members.


Inline/Out-of-Line Member
Functions
• Inline functions:
• are defined within the body of the class
definition.

• Out-of-line functions:
• are declared within the body of the class
definition and defined outside.
Inline/Out-of-Line Member
Functions

• If a member function is defined outside the class


• Scope resolution operator (::) and class name are needed
• Defining a function outside a class does not change it being public or
private

• Binary scope resolution operator (::)


• Combines the class name with the member function name
• Different classes can have member functions with the same name

returnType ClassName::MemberFunctionName( ){

}
Member Functions
Separating Declaration from Implementation
class Circle
{
private: Class must define a
double radius; no-argument
public: constructor too….
Circle(double radius)
{ this->radius = radius; }
double getArea( ); // Not implemented yet
};
double Circle::getArea()
{ return this->radius * radius * 3.14159; }
void main()
{
Circle C1(99.0);
cout<<“Area of circle = “<<C1.getArea();
}
1 // Fig. 6.3: fig06_03.cpp
2 // Time class.
3 #include <iostream>
4
5 using std::cout;
6 using std::endl;
7
8 // Time abstract data type (ADT) definition
9 class Time {
10 public:
11 Time(); // constructor
12 void setTime( int, int, int ); // set hour, minute, second
13 void printMilitary(); // print military time format
14 void printStandard(); // print standard time format
15 private:
16 int hour; // 0 – 23
17 int minute; // 0 – 59
18 int second; // 0 – 59
19 };
20 Note the :: preceding
21 // Time constructor initializes each data member to zero. the function names.
22 // Ensures all Time objects start in a consistent state.
23 Time::Time() { hour = minute = second = 0; }
24
25 // Set a new Time value using military time. Perform validity
26 // checks on the data values. Set invalid values to zero.
27 void Time::setTime( int h, int m, int s )
28 {
29 hour = ( h >= 0 && h < 24 ) ? h : 0;
30 minute = ( m >= 0 && m < 60 ) ? m : 0;
31 second = ( s >= 0 && s < 60 ) ? s : 0;
33
34 // Print Time in military format
35 void Time::printMilitary()
36 {
37 cout << ( hour < 10 ? "0" : "" ) << hour << ":"
38 << ( minute < 10 ? "0" : "" ) << minute;
39 }
40
41 // Print Time in standard format
42 void Time::printStandard()
43 {
44 cout << ( ( hour == 0 || hour == 12 ) ? 12 : hour % 12 )
45 << ":" << ( minute < 10 ? "0" : "" ) << minute
46 << ":" << ( second < 10 ? "0" : "" ) << second
47 << ( hour < 12 ? " AM" : " PM" );
48 }
49
Private Member Functions
• Private Member Functions:
• Only accessible (callable) from member
functions of the class

• No direct access possible (with object instance


of the class)

• Can be: inline / out-of-line


Private Member
Functions
(out-of-line)
Access Modifiers/Specifier
• Access modifiers are used to set access levels for
variables, methods, and constructors
• private, public, and protected
• In C++, default accessibility is private
• The default constructor (provided by compiler) is always public.
Member Access Specifiers
• Programmer can specify a constructor to be private (no use) or public
• public
• Presents clients with a view of the services the class provides
(i.e., interface)
• Data and member functions are accessible (outside class)

• private
• Default access mode
• Data only accessible to member functions and friends
• private members only accessible through the public class
interface using public member functions
Data Hiding - Data Field Encapsulation
• A key feature of OOP is data hiding
• data is concealed within a class so that it cannot be accessed
mistakenly by functions outside the class.

• To prevent direct modification of class attributes (outside


the class), the primary mechanism for hiding data is to
put it in a class and make it private using private keyword.
This is also known as data field encapsulation.
Hidden from Whom?
• Data hiding means hiding data from parts of the program
that don’t need to access it. More specifically, one class’s
data is hidden from other classes.

• Data hiding is designed to protect well-intentioned


programmers from mistakes.
A Simple Program – Accessing Member Function
class Circle
{ C1 Object Instance
private:
double radius;

public: : C1
Circle()
radius: 5.0
{ radius = 5.0; }
double getArea()
{ return radius * radius * 3.14159; } Allocate memory
}; for radius

void main()
{
Circle C1;
//C1.radius = 10; can’t access private member outside the class
cout<<“Area of circle = “<<C1.getArea();
}
A Simple Program – Default Constructor
class Circle
{ C1 Object Instance
private:
double radius;
public:
//Default Constructor : C1
Circle()
//
{ No Constructor
} Here
radius: Any Value

double getArea()
{ return radius * radius * 3.14159; } Allocate memory
}; for radius

void main()
{
Circle C1;
//C1.radius = 10; can’t access private member outside the class
cout<<“Area of circle = “<<C1.getArea();
}
Object Construction with Arguments
 The syntax to declare an object using a constructor with
arguments is:

ClassName objectName(arguments);

 For example, the following declaration creates an object


named circle1 by invoking the Circle class’s constructor
with a specified radius 5.5.

Circle circle1(5.5);
A Simple Program – Constructor with Arguments
class Circle
{ C1 Object Instance
private:
double radius;
public:
Circle( ) {} : C1
Circle(double rad)
radius: 9.0
{ radius = rad; }
double getArea()
{ return radius * radius * 3.14159; } Allocate memory
}; for radius

void main()
{
Circle C1(9.0);
//C1.radius = 10; can’t access private member outside the class
cout<<“Area of circle = “<<C1.getArea();
}
Output of the following Program?
class Circle
{
private:
double radius;

public:
Circle( ) { }

Circle(double rad)
{ radius = rad; }
double getArea()
{ return radius * radius * 3.14159; }
};
void main()
{
Circle C1;
cout<<“Area of circle = “<<C1.getArea();
}
const Member Functions
• const Member Functions: Read-only functions cannot
modify object’s data members
Constant Functions
class Circle
{
private:
double radius;
public:
Circle ()
{ radius = 1; }
Circle(double rad)
{ radius = rad; } const member
double getArea() const function cannot
{ return radius * radius * 3.14159; } update/change
}; object’s data
void main()
{
Circle C2(8.0);
Circle C1;
cout<<“Area of circle = “<<C1.getArea();
}
Accessors and Mutators(Getters &
Setters)
• Accessors: member function only reads/gets value
from a class’s member variable but does not change it.
• Mutators: member function that stores a value in
member variable
const Objects
• const Object: Read-only objects

• Object data members can only be read, NO write/update of


data member allowed
• Requires all member functions be const (except
constructors and destructors)
• const object must be initialized (using constructors) at the
time of object creation
const Objects
• const property of an object goes into effect after the
constructor finishes executing and ends before the class's
destructor executes
• So the constructor and destructor can modify
the object
Pointers to Objects
• You can also define pointers to class objects

• You can use * and . operators OR -> to access members:


Pointers to Objects
• Dynamic Object Creation
Reference to Objects
• Reference is an alias to an existing object
Reference to Objects
Reference and Pointers to Objects
Constructors and Destructors
Interface vs
Implementation

• Separating interface from implementation


• Makes it easier to modify programs

• Header files
• Contains class definitions and function prototypes

• Source-code files
• Contains member function definitions
1 // Fig. 6.5: time1.h
2 // Declaration of the Time class.
3 // Member functions are defined in time1.cpp

9 // Time abstract data type definition


10 class Time {
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 };
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
 A constructor is a special function used to create an object.
Constructor has exactly the same name as the defining class

 Constructors can be overloaded (i.e., multiple constructors


with different signatures) [Purpose: making it easy to
construct objects with different initial data values).

 A class may be declared without constructors. In this case, a


no-argument constructor with an empty body is implicitly
declared in the class known as default constructor

 Note: Default constructor is provided automatically only if no


constructors are explicitly declared in the class.
Constructors’ Properties

 must have the same name as the class itself.

 do not have a return type—not even void.

 play the role of initializing objects.


Constructors and Destructors
• Constructor is a function in every
class which is called when class
creates its object
• Basically it helps in initializing data
members of the class
• A class may have multiple constructors

• Destructors is a function in every


class which is called when the object of
a class is destroyed
• The main purpose of destructor is to
remove dynamic memories etc.
Initializing Notice that default settings for the three
member variables are set in constructor
prototype. No names are needed; the

Objects
10 // Time abstract data type definition
11 class Time {
defaults are applied in the order the
variables are declared.
12 public:
13 Time( int = 0, int = 0, int = 0 ); // default constructor
14 void setTime( int, int, int ); // set hour, minute, second
15 void printMilitary(); // print military time format
16 void printStandard(); // print standard time format
17 private:
18 int hour; // 0 - 23
19 int minute; // 0 - 59
20 int second; // 0 - 59
21 };
22

Default Parameters in Constructor


70 Same constructor, used in overloaded style
71 int main()
72 {
73 Time t1, // all arguments defaulted
74 t2(2), // minute and second defaulted
75 t3(21, 34), // second defaulted
76 t4(12, 25, 42), // all values specified
77 t5(27, 74, 99); // all bad values specified
78
79 cout << "Constructed with:\n"
80 << "all arguments defaulted:\n ";
81 t1.printMilitary();
82 cout << "\n ";
83 t1.printStandard();
84
85 cout << "\nhour specified; minute and second defaulted:"
86 << "\n ";
87 t2.printMilitary();
88 cout << "\n ";
89 t2.printStandard();
90
91 cout << "\nhour and minute specified; second defaulted:"
92 << "\n ";
93 t3.printMilitary();
94 cout << "\n ";
95 t3.printStandard();
96
97 cout << "\nhour, minute, and second specified:"
98 << "\n ";
99 t4.printMilitary();
100 cout << "\n ";
101 t4.printStandard();
102
103 cout << "\nall invalid values specified:"
104 << "\n ";
105 t5.printMilitary();
106 cout << "\n ";
107 t5.printStandard();
108 cout << endl;
109
110 return 0;
111 }
OUTPUT When only hour is
Constructed with: specified, minute and
all arguments defaulted:
second are set to their
00:00
12:00:00 AM
default values of 0.
hour specified; minute and second defaulted:
02:00
2:00:00 AM
hour and minute specified; second defaulted:
21:34
9:34:00 PM
hour, minute, and second specified:
12:25
12:25:42 PM
all invalid values specified:
00:00
12:00:00 AM
Using Destructors

• Destructors
• Are member function of class
• Perform termination housekeeping before the system reclaims the object’s
memory
• Name is tilde (~) followed by the class name (i.e., ~Time)
• Receives no parameters, returns no value
• One destructor per class (no overloading)
• Destructors cannot be declared const, static
• A destructor can be declared virtual or pure virtual
Destructors
When Constructors and Destructors Are Called
Constructors and destructors called automatically
• Order depends on scope of objects
1. Global scope objects
• Constructors called before any other function (including main)
• Destructors called when main terminates (or exit function
called)
• Destructors not called if program terminates with abort

2. Automatic local objects


• Constructors called when objects are defined
• Destructors called when objects leave scope (lifetime ends)
• Destructors not called if the program ends with exit or
abort
7 class CreateAndDestroy {
8 public:
9 CreateAndDestroy( int ); // constructor
10 ~CreateAndDestroy(); // destructor
11 private:
12 int data;
13 };
14
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 automatic in create)"
69
70 static CreateAndDestroy sixth( 6 );
42
71 cout << " (local static in create)" <<
43 void create( void ); // prototype
72
44 73 CreateAndDestroy seventh( 7 );
45 CreateAndDestroy first( 1 ); // global object 74 cout << " (local automatic in create)"
46 75 }
47 int main()
48 { OUTPUT
49 cout << " (global created before main)" << endl; Object 1 constructor (global created before ma
Object 2 constructor (local automatic in main)
50
Object 3 constructor (local static in main)
51 CreateAndDestroy second( 2 ); // local object Object 5 constructor (local automatic in creat
52 cout << " (local automatic in main)" << endl; Object 6 constructor (local static in create)
53 Object 7 constructor (local automatic in creat
Object 7 destructor
54 static CreateAndDestroy third( 3 ); // local object
Object 5 destructor
55 cout << " (local static in main)" << endl; Object 4 constructor (local automatic in main)
56 Object 4 destructor
57 create(); // call function to create objects Object 2 destructor
Object 6 destructor
58
Object 3 destructor
59 CreateAndDestroy fourth( 4 ); // local object Object 1 destructor
60 cout << " (local automatic in main)" << endl;
61 return 0;
62 }
OUTPUT
Object 1 constructor (global created before main)
Object 2 constructor (local automatic in main)
Object 3 constructor (local static in main)
Object 5 constructor (local automatic in create)
Object 6 constructor (local static in create)
Object 7 constructor (local automatic in create)
Object 7 destructor Notice how the order of the
Object 5 destructor constructor and destructor call
Object 4 constructor (local automatic in main)
Object 4 destructor
depends on the types of variables
Object 2 destructor (automatic, global and static)
Object 6 destructor they are associated with.
Object 3 destructor
Object 1 destructor
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
}
When do Constructors Get Called?

• Class object creation time

• Dynamically allocated object

• Class argument passed by value

• Class object returned by value

• Object Array element (created)


What Constructors Do
• Help in initializing: class data members
Employee( ) { id = 0; }

• Allocate memory for dynamic members


Employee() { char* nameptr = new char[20];}

• Allocate any needed resources


• Such as to open files, etc.
Constructing Arrays of Objects
Complex c_arr[10];
Date date_arr[20];

Issue: There is no way to call argument-


based constructors (non-default) for array
members
Arrays of Objects and Non-Default Constructors

• Trick: declare an array of pointer to


objects
• Allocate and initialize each object in a loop

Date *dates[31];

for (int day = 0; day < 31; ++day)


{
dates[day] = new Date(3, day, 2020);
}
Default Member-wise Assignment
• Assignment operator (=) can be used
to assign an object to another object of
the same type.

• Member-wise assignment: each data


member of the object on the right of
the assignment operator is assigned
individually to the same data member
in the object on the left

Default copy constructor
 A type of constructor that is used to initialize an
object with another object of the same type is
known as default copy constructor.

 It is by default available in all classes

 syntax is ClassName(ClassName &Variable)


Copy Constructor for Class Date

Date::Date(Date &date)
{
// no need to check passed date arg
month = date.month;
day = date.day;
year = date.year;
}
Uses of the Copy Constructor
• Implicitly called in 3 situations:
1. defining a new object from an existing object
2. passing an object by value
3. returning an object by value
Copy Constructor: Defining a New Object

Date d1(02,28,2020);

// init a dynamic object from d1


Date* pdate = new Date(d1);

// init 2 local objects from d1


Date d2(d1);// pass by value
Date d3 = d1;// return value
static, const, and
this Pointer
static Class Members
• static class members
• Shared by all objects of a class
• Efficient, when a single copy of data is enough
• Only the static variable has to be updated
• May seems like global variables, but have class scope
• only accessible to objects of same class

• Initialized at file scope


• Exist even if no instances (objects) of the class exist
• Both variables and functions can be static
• Can be public, private or protected
static Class Variables
• Two-Step Procedure:
1. Declare (Inside Class): static int radius;
2. Define (Outside Class): int
Circle::radius=2;

• 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 Class Variables
• Can be accessed using Class name:
cout<<Employee::count;

• Can be accessed via any class’ object:


cout<<e1.count;

• Can be accessed via Non-Static member functions:


cout<<e1.getCount();

• Can be accessed via Static member functions:


cout<<Employee::Stat_getCount();
cout<<e1.Stat_getCount(); //public
static
Private static Class Variables
• Cannot be accessed using Class name:
// ERROR  cout<<Employee::count;

• Cannot be accessed via class' object:


// ERROR  cout<<e1.count;

• Can be accessed via Non-Static member functions:


cout<<e1.getCount();

• Can be accessed via Static member functions:


cout<<Employee::Stat_getCount();
cout<<e1.Stat_getCount(); //public
static
static Class Functions
• Non-static function:
• Can access: static/non-static data members
and static/non-static methods

• Static functions:
• Can access: static data and static
functions
• Cannot access: non-static data, non-
static functions, and this pointer
Public static Class Functions
•Can be invoked using class’s any
object:
cout<<e1.getCount();

•Can be invoked using Class name:


cout<<Employee::getCount();
Private static Class Functions
•Cannot be invoked using class’s object
//ERROR  cout<<e1.getCount();

•Cannot be invoked using Class name


//ERROR 
cout<<Employee::getCount();

•Can be invoked within Class:


• Static member functions
• Non-Static member functions
1 // Fig. 7.9: employ1.h
2 // An employee class

5
6 class Employee {
7 public:
8 Employee( const char*, const char* ); // constructor
9 ~Employee(); // destructor
10 const char *getFirstName() const; // return first name
11 const char *getLastName() const; // return last name
12
13 // static member function
14 static int getCount(); // return # objects instantiated
15
16 private:
static member function and
variable declared.
17 char *firstName;
18 char *lastName;
19
20 // static data member
21 static int count; // number of objects instantiated
22 };
23
25 // Fig. 7.9: employ1.cpp
26 // Member function definitions for class Employee
27 #include <iostream>
28
29 using std::cout;
30 using std::endl; static data member count and
31 function getCount( ) initialized at
32 #include <cstring> file scope (required).
33 #include <cassert>
34 #include "employ1.h"
35
36 // Initialize the static data member
37 int Employee::count = 0;
38
39 // Define the static member function that
40 // returns the number of employee objects instantiated.
41 int Employee::getCount() { return count; } Note the use of
42 assert to test for
43 // Constructor dynamically allocates space for the
memory allocation.
44 // first and last name and uses strcpy to copy
45 // the first and last names into the object
46 Employee::Employee( const char *first, const char *last )
47 {
48 firstName = new char[ strlen( first ) + 1 ];
49 assert( firstName != 0 ); // ensure memory allocated
50 strcpy( firstName, first ); static data member
51 count changed when a
52 lastName = new char[ strlen( last ) + 1 ];
53 assert( lastName != 0 ); // ensure memory allocated
constructor/destructor
54 strcpy( lastName, last ); called.
55
56 ++count; // increment static count of employees
57 cout << "Employee constructor for " << firstName
58 << ' ' << lastName << " called." << endl;
59 }
60
61 // Destructor deallocates dynamically allocated memory
62 Employee::~Employee() static data member count
63 { changed when a
64 cout << "~Employee() called for " << firstName constructor/destructor called.
65 << ' ' << lastName << endl;
66 delete [] firstName; // recapture memory
67 delete [] lastName; // recapture memory Count decremented
68 --count; // decrement static count of employees
because of
69 } destructor calls from
70 delete.
71 // Return first name of employee
72 const char *Employee::getFirstName() const
73 {
74 // Const before return type prevents client from modifying
75 // private data. Client should copy returned string before
76 // destructor deletes storage to prevent undefined pointer.
77 return firstName;
78 }
79
80 // Return last name of employee
81 const char *Employee::getLastName() const
82 {
83 // Const before return type prevents client from modifying
84 // private data. Client should copy returned string before
85 // destructor deletes storage to prevent undefined pointer.
86 return lastName;
87 }
88 // Fig. 7.9: fig07_09.cpp
89 // Driver to test the employee class
90 #include <iostream> If no Employee objects exist
91 count incremented because of getCount must be accessed
92 using std::cout; constructor calls from new. using the class name and (::).
93 using std::endl;
94
95 #include "employ1.h"
96 Number of employees before instantiation is 0
97 int main()
98 {
99 cout << "Number of employees before instantiation is "
100 << Employee::getCount() << endl; // use class name
e2Ptr->getCount() or Employee::getCount() would
101 also work.
102 Employee *e1Ptr = new Employee( "Susan", "Baker" );
103 Employee *e2Ptr = new Employee( "Robert", "Jones" );
104 Number of employees after instantiation is 2
105 cout << "Number of employees after instantiation is "
106 << e1Ptr->getCount();
107 Employee constructor for Susan Baker called.
108 cout << "\n\nEmployee 1: " Employee constructor for Robert Jones called.
109 << e1Ptr->getFirstName()
110 << " " << e1Ptr->getLastName() Employee 1: Susan Baker
111 << "\nEmployee 2: " Employee 2: Robert Jones
112 << e2Ptr->getFirstName()
113 << " " << e2Ptr->getLastName() << "\n\n";
114
115 delete e1Ptr; // recapture memory ~Employee() called for Susan Baker
116 e1Ptr = 0; ~Employee() called for Robert Jones
117 delete e2Ptr; // recapture memory
118 e2Ptr = 0;
119

120 cout << "Number of employees after deletion is "

121 << Employee::getCount() << endl;

122

123 return 0;
count back to zero.
124 }

Number of employees before instantiation is 0


Employee constructor for Susan Baker called.
Employee constructor for Robert Jones called.
Number of employees after instantiation is 2

Employee 1: Susan Baker


Employee 2: Robert Jones

~Employee() called for Susan Baker


~Employee() called for Robert Jones
Number of employees after deletion is 0
const Class Members
• As with member functions, data members can also be
const

• Member Initializer List:


• Can be used to initialize both const and non-const
data members
• consts and references must be initialized using
member initializer
Member Initializer List (Non-const
Members)
Member Initializer List (non-
static const)
Member Initializer List
(References)
Member Initializer List (member object, no default
constructor)
Member Initializer List
(parameter name same as
data member)
Member Initializer List
(base class members)

Will be discussed in chapters


after midterm
Using the this Pointer
• Examples using this
• For a member function print data member x, either
this->x;
or
(*this).x

• Cascaded member function calls:


• Function returns a reference pointer to the same object
{ return *this; }
• Other functions can operate on that pointer
Using the this Pointer
• Example of cascaded member function calls:
• Member functions setHour, setMinute, and setSecond all
return *this (reference to an object)

• For object t, consider:


t.setHour(1).setMinute(2).setSecond
(3);

• Executes t.setHour(1), returns *this (reference to object)


and the expression becomes
t.setMinute(2).setSecond(3);

• Executes t.setMinute(2), returns reference and becomes


t.setSecond(3);

• Executes t.setSecond(3), returns reference and becomes


1 // Fig. 7.7: fig07_07.cpp
2 // Using the this pointer to refer to object members.
3 #include <iostream>
4
5 using std::cout;
6 using std::endl;
7
8 class Test {
9 public:
10 Test( int = 0 ); // default constructor
11 void print() const;
12 private:
13 int x;
Printing x directly.
14 };
15
16 Test::Test( int a ) { x = a; } // constructor
17
18 void Test::print() const // ( ) around *this required Print x using the arrow ->
19 { operator off the this pointer.
20 cout << " x = " << x
21 << "\n this->x = " << this->x
22 << "\n(*this).x = " << ( *this ).x << endl;
23 }
24
25 int main()
26 {
27 Test testObject( 12 );
28 Printing x using the dot (.) operator. Parenthesis
29 testObject.print(); required because dot operator has higher
30 precedence than *. Without, interpreted
31 return 0; incorrectly as *(this.x).
32 }
x = 12
this->x = 12
(*this).x = 12

All three methods


have the same result.
1 // Fig. 7.8: time6.h
2 // Cascading member function calls.
3
4 // Declaration of class Time.
5 // Member functions defined in time6.cpp
6
7
8
9 class Time {
10 public:
11 Time( int = 0, int = 0, int = 0 ); // default constructor
12
13 // set functions
14 Time &setTime( int, int, int ); // set hour, minute, second
15 Time &setHour( int ); // set hour
16 Time &setMinute( int ); // set minute
17 Time &setSecond( int ); // set second Noticethe Time & - function
18
returns a reference to a Time
19 // get functions (normally declared const)
20 int getHour() const; // return hour object.
21 int getMinute() const; // return minute Specify object in function definition.
22 int getSecond() const; // return second
23
24 // print functions (normally declared const)
25 void printMilitary() const; // print military time
26 void printStandard() const; // print standard time
27 private:
28 int hour; // 0 - 23
29 int minute; // 0 - 59
30 int second; // 0 - 59
31 };
32
33
34 // Fig. 7.8: time.cpp
35 // Member function definitions for Time class.
36 #include <iostream>
37
38 using std::cout;
39
40 #include "time6.h"
41
42 // Constructor function to initialize private data.
43 // Calls member function setTime to set variables.
44 // Default values are 0 (see class definition).
45 Time::Time( int hr, int min, int sec )
46 { setTime( hr, min, sec ); }
47
48 // Set the values of hour, minute, and second.
49 Time &Time::setTime( int h, int m, int s )
Returning *this enables
50 { cascading function calls
51 setHour( h );
52 setMinute( m );
53 setSecond( s );
54 return *this; // enables cascading
55 }
56
57 // Set the hour value
58 Time &Time::setHour( int h )
59 {
60 hour = ( h >= 0 && h < 24 ) ? h : 0;
61
62 return *this; // enables cascading
63 }
64
65 // Set the minute value
66 Time &Time::setMinute( int m )
67 {
68 minute = ( m >= 0 && m < 60 ) ? m : 0;
69
70 return *this; // enables cascading
71 }
72
Returning *this enables
73 // Set the second value
cascading function calls
74 Time &Time::setSecond( int s )
75 {
76 second = ( s >= 0 && s < 60 ) ? s : 0;
77
78 return *this; // enables cascading
79 }
80
81 // Get the hour value
82 int Time::getHour() const { return hour; }
83
84 // Get the minute value
85 int Time::getMinute() const { return minute; }
86
87 // Get the second value
88 int Time::getSecond() const { return second; }
89
90 // Display military format time: HH:MM
91 void Time::printMilitary() const
92 {
93 cout << ( hour < 10 ? "0" : "" ) << hour << ":"
94 << ( minute < 10 ? "0" : "" ) << minute;
95 }
96
97 // Display standard format time: HH:MM:SS AM (or PM) printStandard does not
98 void Time::printStandard() const return a reference to an object.
99 {
100 cout << ( ( hour == 0 || hour == 12 ) ? 12 : hour % 12 )
101 << ":" << ( minute < 10 ? "0" : "" ) << minute
102 << ":" << ( second < 10 ? "0" : "" ) << second
103 << ( hour < 12 ? " AM" : " PM" );
104 }
105 // Fig. 7.8: fig07_08.cpp
106 // Cascading member function calls together
107 // with the this pointer
108 #include <iostream> Notice cascading function calls.
109
110 using std::cout;
111 using std::endl;
112
113 #include "time6.h"
114
115 int main()
116 {
117 Time t;
118
119 t.setHour( 18 ).setMinute( 30 ).setSecond( 22 );
120 cout << "Military time: "; Cascading function calls. printStandard must be called
121 t.printMilitary(); after setTime because printStandard does not return
122 cout << "\nStandard time: "; a reference to an object.
123 t.printStandard(); t.printStandard().setTime(); would cause an
124 error.
125 cout << "\n\nNew standard time: ";
126 t.setTime( 20, 20, 20 ).printStandard();
127 cout << endl;

128

129 return 0;

130 }

Military time: 18:30


Standard time: 6:30:22 PM

New standard time: 8:20:20 PM


What is the Singleton Pattern?

• Software design pattern is a general, reusable solution to


a commonly occurring problem within a given context in
software design.

• The Singleton pattern ensures that a class is only


instantiated once and provides a global access point for
this instance
Why use the Singleton
Pattern?
• It is important for some classes to only have one instance

• It is also important that this single instance is easily


accessible

• Why not use a global object?


• Global variables make objects accessible, but they
don't prevent the instantiation of multiple objects.
Solution
• Make the class responsible for keeping track of its only
instance:
• The class can ensure that no other instances are
created
• This is the Singleton pattern
Examples of Singleton Patterns

• HR Manager
• Head of Department
• Print spooler
• Window Managers
• Digital Filters
• Accounting Systems
•…
Design Solution
• Defines a getInstance( ) operation that lets clients access
its unique instance
• Responsible for creating its own unique instance

Singleton

-static uniqueinstance
Singleton data
… -Singleton()
return uniqueinstance; +static getInstance()
Singleton methods…
Implementation
• Declare all of class’s constructors private
• prevent other classes from directly creating an instance of this
class

• Hide the operation that creates the instance behind a


class operation (getInstance)

• Variation: Since creation policy is encapsulated in


getInstance, it is possible to vary the creation policy
Singleton Example (C++)
class Database
{
private:
static Database *DB;
...
//private constructor
In application code…
Database() { ... }
Database *db =
public:
Database::getDB();
//static method
db.getDB();
static Database *getDB()
db->someMethod();
{
if (DB == NULL)
DB = new
Database());

return DB;
}
...
};
Database* Database::DB=NULL;
Singleton Consequences

• Ensures only one (e.g., Database) instance exists in the system

• Can maintain a pointer (need to create object on first get call) or an


actual object

• Can also use this pattern to control fixed multiple instances

• Much better than the alternative: global variables

You might also like