You are on page 1of 16

11.1 Introduction 11.

2 Structure Definitions
• Object-oriented programming (OOP) • Structures
– Encapsulates data (attributes) and functions (behavior) into – Aggregate data types built using elements of other types
packages called classes
struct Time {
• Information hiding Structure tag
int hour;
– Implementation details are hidden within the classes
int minute; Structure members
themselves
int second;
• Classes };
– Classes are the standard unit of programming – Members of the same structure must have unique names
– A class is like a blueprint – reusable – Two different structures may contain members of the same
– Objects are instantiated (created) from the class name
– For example, a house is an instance of a “blueprint class” – Each structure definition must end with a semicolon

11.2 Structure Definitions 11.3 Accessing Members of Structures


• Self-referential structure • Member access operators:
– Contains a member that is a pointer to the same structure – Dot operator (.) for structures and objects
type – Arrow operator (->) for pointers
– Used for linked lists, queues, stacks and trees – Print member hour of timeObject:
• struct cout << timeObject.hour;
– Creates a new data type that is used to declare variables OR
timePtr = &timeObject;
– Structure variables are declared like variables of other types cout << timePtr->hour;
– Example: – timePtr->hour is the same as ( *timePtr ).hour
Time timeObject, timeArray[ 10 ],
*timePtr, &timeRef = timeObject; – Parentheses required: * has lower precedence than .

1 // test. 11.1: test11_01.cpp 32 // set members to invalid values 6


2 // Create a structure, set its members, and print it. 33 dinnerTime.hour = 29;
3 #include <iostream>
34 dinnerTime.minute = 73;
4
35
5 using std::cout;
6 using std::endl; 36 cout << "\nTime with invalid values: ";
7 37 printMilitary( dinnerTime );
Time with invalid values: 29:73
8 struct Time { // structure definition 38 cout << endl;
9 int hour; // 0-23
39 return 0;
10 int minute; // 0-59
11 int second; // 0-59
Creates the user-defined structure 40 }

11 };
type Time with three integer 41
13
2. Create a struct data type members: hour, minute and 42 // Print the time in military format
14 void printMilitary( const Time & ); second.
// prototype 43 void printMilitary( const Time &t )
15 void printStandard( const Time & ); // prototype 44 {
16
45 cout << ( t.hour < 10 ? "0" : "" ) << t.hour << ":"
17 int main()
18 { 46 << ( t.minute < 10 ? "0" : "" ) << t.minute;
19 Time dinnerTime; // variable of new type Time 47 }
20 48
21 // set members to valid values 49 // Print the time in standard format
22 dinnerTime.hour = 18;
50 void printStandard( const Time &t )
23 dinnerTime.minute = 30;
51 {
24 dinnerTime.second = 0;
25 52 cout << ( ( t.hour == 0 || t.hour == 11 ) ?
26 cout << "Dinner will be held at "; 53 11 : t.hour % 11 )
27 printMilitary( dinnerTime ); Dinner will be held at 18:30 military time, 54 << ":" << ( t.minute < 10 ? "0" : "" ) << t.minute
28 cout << " military time,\nwhich is "; which is 6:30:00 PM standard time. 55 << ":" << ( t.second < 10 ? "0" : "" ) << t.second
29 printStandard( dinnerTime );
56 << ( t.hour < 11 ? " AM" : " PM" );
30 cout << " standard time.\n";
31 57 }

1
7

Dinner will be held at 18:30 military time,


which is 6:30:00 PM standard time.
11.4 Implementing an Abstract Data Type with a
Time with invalid values: 29:73 • Program Class
Output

11.5 Implementing a Time Abstract Data Type with


a Class
• Member access specifiers
– Classes can limit the access to their member functions and data
– The three types of access a class can grant are:
• Public — Accessible wherever the program has access to an
object of the class
• private — Accessible only to member functions of the class
• Protected — Similar to private and discussed later

• Constructor
– Special member function that initializes the data members of a
class object
– Cannot return values
– Have the same name as the class

11.5 Implementing a Time Abstract Data Type


with a Class
• Class definition and declaration
– Once a class has been defined, it can be used as a type in
object, array and pointer declarations
– Example:
Time sunset, // object of type Time
arrayOfTimes[ 5 ], // array of Time objects
*pointerToTime, // pointer to a Time object
&dinnerTime = sunset; // reference to a Time object

Note: The class name


becomes the new type
specifier.

2
1 // test. 11.3: test11_03.cpp 13 33 14
2 // Time class. 34 // Print Time in military format
3 #include <iostream> 35 void Time::printMilitary()
4 36 {
5 using std::cout;
37 cout << ( hour < 10 ? "0" : "" ) << hour << ":"
6 using std::endl;
38 << ( minute < 10 ? "0" : "" ) << minute;
7
39 }
8 // Time abstract data type (ADT) definition
40
9 class Time {
10 public: 41 // Print Time in standard format
11 Time(); // constructor 42 void Time::printStandard()
11 void setTime( int, int, int ); // set hour, minute, second 43 {
13 void printMilitary(); // print military time format 44 cout << ( ( hour == 0 || hour == 11 ) ? 11 : hour % 11 )
14 void printStandard(); // print standard time format 45 << ":" << ( minute < 10 ? "0" : "" ) << minute
15 private: 46 << ":" << ( second < 10 ? "0" : "" ) << second
16 int hour; // 0 – 23 47 << ( hour < 11 ? " AM" : " PM" );
17 int minute; // 0 – 59
48 }
18 int second; // 0 – 59
49
19 };
50 // Driver to test simple class Time
20
21 // Time constructor initializes each data member to zero. 51 int main()
22 // Ensures all Time objects start in a consistent state. 52 {
Note the :: preceding
23 Time::Time() { hour = minute = second = 0; } 53 Time t; // instantiate object t of class The
Timeinitial military time is 00:00
the function names. The initial standard time is 11:00:00 AM
24 54
25 // Set a new Time value using military time. Perform validity 55 cout << "The initial military time is ";
26 // checks on the data values. Set invalid values to zero. 56 t.printMilitary(); Notice how functions are
27 void Time::setTime( int h, int m, int s ) 57 cout << "\nThe initial standard time is "; called using the dot (.)
28 { 58 t.printStandard(); operator.
29 hour = ( h >= 0 && h < 24 ) ? h : 0;
59
30 minute = ( m >= 0 && m < 60 ) ? m : 0;
31 second = ( s >= 0 && s < 60 ) ? s : 0;
32 }

60 t.setTime( 13, 27, 6 ); 15


61 cout << "\n\nMilitary time after setTime is ";
62 t.printMilitary();
11.5 Implementing a Time Abstract Data Type
63
64
cout << "\nStandard time after setTime is ";
t.printStandard();
with a Class
Military time after setTime is 13:27
65
66 t.setTime( 99, 99, 99 );
Standard time after setTime is 1:27:06 PM
// attempt invalid settings
• Destructors
67 cout << "\n\nAfter attempting invalid settings:" – Functions with the same name as the class but preceded with
68 << "\nMilitary time: ";
69 t.printMilitary();
a tilde character (~)
70 cout << "\nStandard time: "; – Cannot take arguments and cannot be overloaded
71 t.printStandard(); After attempting invalid settings:
72 cout << endl;
Military time: 00:00
– Performs “termination housekeeping”
73 return 0;
74 }
Standard time: 11:00:00 AM
• Binary scope resolution operator (::)
The initial military time is 00:00
– Combines the class name with the member function name
The initial standard time is 11:00:00 AM
– Different classes can have member functions with the same
Military time after setTime is 13:27
Standard time after setTime is 1:27:06 PM
name
After attempting invalid settings: • Format for defining member functions
Military time: 00:00
Standard time: 11:00:00 AM ReturnType ClassName::MemberFunctionName( ){

}

11.5 Implementing a Time Abstract Data Type


11.6 Class Scope and Accessing Class Members
with a Class
• If a member function is defined inside the class • Class scope
– Scope resolution operator and class name are not needed – Data members and member functions
– Defining a function outside a class does not change it being • File scope
public or private
– Nonmember functions
• Classes encourage software reuse • Inside a scope
– Inheritance allows new classes to be derived from old ones
– Members accessible by all member functions
• Referenced by name
• Outside a scope
– Members are referenced through handles
• An object name, a reference to an object or a pointer to an
object

3
1 // test. 11.4: test11_04.cpp 20
2 // Demonstrating the class member access operators . and ->

11.6 Class Scope and Accessing Class Members 3 //


4 // CAUTION: IN FUTURE EXAMPLES WE AVOID PUBLIC DATA!
5 #include <iostream> It is rare to have
• Function scope 6
7 using std::cout;
public member
variables. Usually
– Variables only known to function they are defined in 8 using std::endl;
9
only member
functions are
– Variables are destroyed after function completion 10 // Simple class Count
public; this
11 class1. Class
Count definition
{
keeps as much
• Accessing class members 11
13
public:
2. Create an object of the class
int x; information hidden
2.1 Assign a value to the object. Print the value using the dot operator
as possible.
– Same as structs 14 void print() { cout << x << endl; }
15 }; 2.2 Set a new value and print it using a reference
– Dot (.) for objects and arrow (->) for pointers 16
17 int main()
– Example: 18 {
• t.hour is the hour element of t 19 Count counter, // create counter object
20 *counterPtr = &counter, // pointer to counter
• TimePtr->hour is the hour element 21 &counterRef = counter; // reference to counter
22
23 cout << "Assign 7 to x and print using the object's name: ";
24 counter.x = 7; // assign 7 to data member x
25 counter.print(); // call member function print
26
27 cout << "Assign 8 to x and print using a reference: ";
28 counterRef.x = 8; // assign 8 to data member x
29 counterRef.print(); // call member function print
30

31 cout << "Assign 10 to x and print using a pointer: "; 21


32 counterPtr->x = 10; // assign 10 to data member x

33 counterPtr->print(); // call member function print 11.7 Separating Interface from Implementation
34 return 0;
35 } • Separating interface from implementation
– Makes it easier to modify programs
Assign 7 to x and print using the object's name: 7
– Header files
Assign 8 to x and print using a reference: 8
Assign 10 to x and print using a pointer: 10
• Contains class definitions and function prototypes
– Source-code files
• Contains member function definitions

1 // test. 11.5: time1.h 23 23 // test. 11.5: time1.cpp 24


24 // Member function definitions for Time class.
2 // Declaration of the Time class.
25 #include <iostream>
3 // Member functions are defined in time1.cpp 26
27 using std::cout;
28 Source file uses #include
29 #include "time1.h"
30
to load the header file
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
9 // Time abstract data type definition 35 // Set a new Time value using military time. Perform validity
36 // checks on the data values. Set invalid values to zero.
10 class Time { 37 void Time::setTime( int h, int m, int s )
11 public: 38 {
39 hour = ( h >= 0 && h < 24 ) ? h : 0;
11 Time(); // constructor 40 minute = ( m >= 0 && m < 60 ) ? m : 0;
41 second = ( s >= 0 && s < 60 ) ? s : 0;
13 void setTime( int, int, int ); // set hour, minute, second Source file contains
42 }
14 void printMilitary(); // print military time format 43 function definitions
44 // Print Time in military format
15 void printStandard(); // print standard time format
45 void Time::printMilitary()
16 private: 46 {
47 cout << ( hour < 10 ? "0" : "" ) << hour << ":"
17 int hour; // 0 - 23
48 << ( minute < 10 ? "0" : "" ) << minute;
18 int minute; // 0 - 59 49 }
50
19 int second; // 0 - 59
51 // Print time in standard format
20 }; 52 void Time::printStandard()
53 {
21
54 cout << ( ( hour == 0 || hour == 11 ) ? 11 : hour % 11 )
55 << ":" << ( minute < 10 ? "0" : "" ) << minute
56 << ":" << ( second < 10 ? "0" : "" ) << second
57 << ( hour < 11 ? " AM" : " PM" );
58 }

4
1 // test. 11.6: test11_011.cpp 26
2 // Demonstrate errors resulting from attempts
3 // to access private class members.
11.8 Controlling Access to Members 4 #include <iostream>
5
6 using std::cout;
• public 7
8 #include "time1.h"
– Presents clients with a view of the services the class provides 9
10 int main()
(interface) 11 {
11 Time t;
– Data and member functions are accessible 13
14 // Error: 'Time::hour' is not accessible
• private 15 t.hour = 7; Attempt to modify private member
16 variable hour.
– Default access mode 17 // Error: 'Time::minute' is not accessible
18 cout << "minute = " << t.minute;
– Data only accessible to member functions and friends 19 Attempt to access private member
20 return 0; variable minute.
– private members only accessible through the public 21 }

class interface using public member functions


Compiling...
test11_011.cpp
D:\test11_011.cpp(15) : error C2248: 'hour' : cannot access private
member declared in class 'Time'
D:\test6_06\time1.h(18) : see declaration of 'hour'
D:\test11_011.cpp(18) : error C2248: 'minute' : cannot access private
member declared in class 'Time'
D:\time1.h(19) : see declaration of 'minute'
Error executing cl.exe.

test.exe - 2 error(s), 0 warning(s)

87 // test. 11.7: test11_011.cpp 28


88 // Demonstrating a utility function

11.9 Access Functions and Utility Functions 89 // Compile with salesp.cpp


90 #include "salesp.h"
Create object s, an instance
91
of class SalesPerson
• Utility functions 92 int main()
93 {
– private functions that support the operation of public 94 SalesPerson s; // create SalesPerson object s
95
functions 96 s.getSalesFromUser(); // note simple sequential code
– Not intended to be used directly by clients 97 s.printAnnualSales(); // no control structures in main
98 return 0;
• Access functions 99 }
Use access functions to gather
– public functions that read/display data or check conditions OUTPUT and print data
Enter sales amount for month 1: 5314.76 (getSalesFromUser and
– Allow public functions to check private data Enter sales amount for month 2: 4292.38
printAnnualSales). Utility
Enter sales amount for month 3: 4589.83
Enter sales amount for month 4: 5534.03 functions actually calculate the
Enter sales amount for month 5: 43711.34 total sales, but the user is not
Enter sales amount for month 6: 5698.45
• Following example Enter sales
Enter sales
amount
amount
for
for
month
month
7: 4439.22
8: 5893.57
aware of these function calls.
Notice how simple main() is –
– Program to take in monthly sales and output the total Enter sales
Enter sales
amount
amount
for
for
month
month
9: 4909.67
10: 5113.45 there are no control structures,
Enter sales amount for month 11: 4024.97
– Implementation not shown, only access functions Enter sales amount for month 11: 5923.92
only function calls. This hides
the implementation of the
The total annual sales are: $60110.59 program.

1 // test. 11.8: time2.h 30


2 // Declaration of the Time class.

11.10 Initializing Class Objects: Constructors 3 // Member functions are defined in time2.cpp

• Constructors
– Initialize class members
– Same name as the class
– No return type 10 // Time abstract data type definition
11 class Time {
– Member variables can be initialized by the constructor or set 11 public: Notice that default settings
afterwards 13 Time( int = 0, int = 0, int = 0 ); // default constructor for the three member
14 void setTime( int, int, int ); // set hour, minute, second variables are set in
• Passing arguments to a constructor 15 void printMilitary(); // print military time format
constructor prototype. No
names are needed; the
– When an object of a class is declared, initializers can be 16 void printStandard(); // print standard time format
defaults are applied in the
provided 17 private:
order the member variables
18 int hour; // 0 - 23 are declared.
– Format of declaration with initializers: 19 int minute; // 0 - 59

Class-type ObjectName( value1,value2,…); 20 int second; // 0 - 59


21 };
– Default arguments may also be specified in the constructor 22
prototype

5
61 // test. 11.8: test11_08.cpp 31 94 cout << "\n "; 32
62 // Demonstrating a default constructor 95 t3.printStandard();
63 // function for class Time. 96
64 #include <iostream> 97 cout << "\nhour, minute, and second specified:"
Notice how objects are initialized: 98 << "\n ";
65
66 using std::cout; Constructor ObjectName(value1,value2…); 99 t4.printMilitary(); • 2.1
67 using std::endl; 100 cout << "\n ";
68
If not enough values are specified, the rightmost
values are set to their defaults.
101 t4.printStandard(); (continued)
69 #include "time2.h" 102
70 103 cout << "\nall invalid values specified:" Print the
71 int main() 104 << "\n ";
72 { 105 t5.printMilitary(); objects.
73 Time t1, // all arguments defaulted 106 cout << "\n ";
74 t2(2), // minute and second defaulted 107 t5.printStandard();
75 t3(21, 34), // second defaulted 108 cout << endl;
76 t4(11, 25, 42), // all values specified 109
77 t5(27, 74, 99); // all bad values specified 110 return 0;
78 111 }
OUTPUT
79 cout << "Constructed with:\n"
Constructed with:
When only hour
80 << "all arguments defaulted:\n "; all arguments defaulted: is specified,
81 t1.printMilitary(); 00:00 minute and
82 cout << "\n "; 11:00:00 AM
83 t1.printStandard(); hour specified; minute and second defaulted:
second are set
84 02:00 to their default
85 cout << "\nhour specified; minute and second defaulted:" 2:00:00 AM values of 0.
hour and minute specified; second defaulted:
86 << "\n ";
21:34
87 t2.printMilitary();
9:34:00 PM
88 cout << "\n "; hour, minute, and second specified:
89 t2.printStandard(); 11:25
90 11:25:42 PM
91 cout << "\nhour and minute specified; second defaulted:" all invalid values specified:
92 << "\n "; 00:00
93 t3.printMilitary(); 11:00:00 AM

11.13 When Constructors and Destructors Are


11.11 Using Destructors
Called
• Destructors • Constructors and destructors called automatically
– Are member function of class – Order depends on scope of objects
– Perform termination housekeeping before the system • Global scope objects
reclaims the object’s memory
– Constructors called before any other function (including main)
– Complement of the constructor
– Destructors called when main terminates (or exit function called)
– Name is tilde (~) followed by the class name (i.e., ~Time)
– Destructors not called if program terminates with abort
• Recall that the constructor’s name is the class name
– Receives no parameters, returns no value • Automatic local objects
– One destructor per class – Constructors called when objects are defined
• No overloading allowed – Destructors called when objects leave scope
• i.e., when the block in which they are defined is exited
– Destructors not called if the program ends with exit or abort

1 // test. 11.9: create.h 36

11.13 When Constructors and Destructors Are 2 // Definition of class CreateAndDestroy.


3 // Member functions defined in create.cpp.
Called
• Static local objects 6
7 class CreateAndDestroy {
– Constructors called when execution reaches the point where 8 public:
the objects are defined 9 CreateAndDestroy( int ); // constructor

– Destructors called when main terminates or the exit 10 ~CreateAndDestroy(); // destructor


11 private:
function is called 11 int data;
– Destructors not called if the program ends with abort 13 };
14

6
16 // test. 11.9: create.cpp 37 33 // test. 11.9: test11_09.cpp 38
34 // Demonstrating the order in which constructors and
17 // Member function definitions for class CreateAndDestroy
35 // destructors are called.
18 #include <iostream> 36 #include <iostream>

19
37
38 using std::cout;
• 3. Create
20 using std::cout;
39 using std::endl; multiple
40
21 using std::endl; 41 #include "create.h" objects of
42
22 43 void create( void ); // prototype varying
44
23 #include "create.h" 45 CreateAndDestroy first( 1 ); // global object types
46
24
47 int main()
25 CreateAndDestroy::CreateAndDestroy( int value ) 48 {
49 cout << " (global created before main)" << endl;
26 { Constructor and Destructor changed to 50
27 data = value;
print when they are called. 51 CreateAndDestroy second( 2 ); // local object
52 cout << " (local automatic in main)" << endl;
28 cout << "Object " << data << " constructor"; 53
54 static CreateAndDestroy third( 3 ); // local object
29 }
55 cout << " (local static in main)" << endl;
30 56
57 create(); // call function to create objects
31 CreateAndDestroy::~CreateAndDestroy() 58
59 CreateAndDestroy fourth( 4 ); // local object
32 { cout << "Object " << data << " destructor " << endl; }
60 cout << " (local automatic in main)" << endl;
61 return 0;
62 }

63 39
64 // Function to create objects
65 void create( void ) 11.14 Using Data Members and Member
66 {
67 CreateAndDestroy fifth( 5 );
Functions
68
69
cout << " (local automatic in create)" << endl;
• Member functions
70
71
static CreateAndDestroy sixth( 6 );
cout << " (local static in create)" << endl;
– Allow clients of the class to set (i.e., write) or get (i.e., read) the
72 values of private data members
73 CreateAndDestroy seventh( 7 );
74 cout << " (local automatic in create)" << endl;
– Example:
75 } Adjusting a customer’s bank balance
OUTPUT
• private data member balance of a class BankAccount
Object 1 constructor (global created before main) could be modified through the use of member function
Object 2 constructor (local automatic in main)
Object 3 constructor (local static in main) computeInterest
Object 5 constructor (local automatic in create)
Object 6 constructor (local static in create) • A member function that sets data member interestRate could
Object
Object
7
7
constructor
destructor
(local automatic in create) be called setInterestRate, and a member function that returns
Object 5 destructor Notice how the order of the the interestRate could be called getInterestRate
Object 4 constructor (local automatic in main)
constructor and destructor call
Object 4 destructor – Providing set and get functions does not make private
Object 2 destructor depends on the types of variables
Object 6 destructor (automatic, global and static) variables public
Object 3 destructor
they are associated with.
Object 1 destructor – A set function should ensure that the new value is valid

1 // test. 11.11: time4.h 42

11.15 A Subtle Trap: Returning a Reference to a 2 // Declaration of the Time class.


3 // Member functions defined in time4.cpp
Private Data Member 4

• Reference to an object
– Alias for the name of the object
Notice how member function
– May be used on the left side of an assignment statement 9 badSetHour returns a reference
– Reference can receive a value, which changes the original 10 class Time { (int & is the return type).
11 public:
object as well 11 Time( int = 0, int = 0, int = 0 );

• Returning references 13
14
void setTime( int, int, int );
int getHour();
– public member functions can return non-const 15 int &badSetHour( int ); // DANGEROUS reference return

references to private data members 16 private:


17 int hour;
• Should be avoided, breaks encapsulation 18 int minute;
19 int second;
20 };
21

7
23 // test. 11.11: time4.cpp 43 52 // test. 11.11: test11_11.cpp 44
24 // Member function definitions for Time class. 53 // Demonstrating a public member function that
25 #include "time4.h" 54 // returns a reference to a private data member.
26 55 // Time class has been trimmed for this example.
27 // Constructor function to initialize private data. • 1. Load 56
57
#include <iostream>
• 1.2 Declare
28 // Calls member function setTime to set variables.
29 // Default values are 0 (see class definition). header 58
59
using std::cout;
using std::endl;
Declare Time object t and reference
30 Time::Time( int hr, int min, int sec ) reference hourRef that is
60
31 { setTime( hr, min, sec ); }
61 #include "time4.h" assigned the reference returned by
32
33 // Set the values of hour, minute, and second.
1.1 Function 62 the call t.badSetHour(20).
• 2. Change
63 int main()
34 void Time::setTime( int h, int m, int s )
35 {
definitions 64 {
data using a
65 Time t;
36 hour = ( h >= 0 && h < 24 ) ? h : 0; 66 int &hourRef = t.badSetHour( 20 ); Hour before modification: 20
37 minute = ( m >= 0 && m < 60 ) ? m : 0; 67 reference
Alias used to set the value of
38 second = ( s >= 0 && s < 60 ) ? s : 0; 68 cout << "Hour before modification: " << hourRef;
hour to 30 (an invalid value).
39 } 69 hourRef = 30; // modification with invalid value
40 70 Hour after modification: 30
cout << "\nHour after modification: " << t.getHour();
41 // Get the hour value
badSetHour returns a
71
72 // Dangerous: Function call that returns
• 3. Output
42 int Time::getHour() { return hour; } Function call used as an lvalue
43 reference to the private 73
74
// a reference can be used as an lvalue!
t.badSetHour(11) = 74;
results
and assigned the value 74
44 // POOR PROGRAMMING PRACTICE: member variable hour. (another invalid value).
75 cout << "\n\n*********************************\n"
45 // Returning a reference to a private data member. Changing this reference 76 << "POOR PROGRAMMING PRACTICE!!!!!!!!\n"
46 int &Time::badSetHour( int hh ) will alter hour as well. 77 << "badSetHour as an lvalue, Hour: " *********************************
47 {
78 << t.getHour()
48 hour = ( hh >= 0 && hh < 24 ) ? hh : 0; POOR PROGRAMMING PRACTICE!!!!!!!!
79 << "\n*********************************" << endl;
49 80 badSetHour as an lvalue, Hour: 74
50 return hour; // DANGEROUS reference return 81 return 0; *********************************
51 } 82 }

Hour before modification: 20


Hour after modification: 30

*********************************
POOR PROGRAMMING PRACTICE!!!!!!!!
11.16 Assignment by Default Memberwise Copy
badSetHour as an lvalue, Hour: 74
*********************************
• Assigning objects
– An object can be assigned to another object of the same type
using the assignment operator (=)
HourRef used to change hour – Member by member copy
to an invalid value. Normally,
the function setbadSetHour • Objects may be
would not have allowed this.
However, because it returned a
– Passed as function arguments
reference, hour was changed – Returned from functions (call-by-value default)
directly.

1 // test. 11.11: test11_11.cpp 47 31 48


2 // Demonstrating that class objects can be assigned 32 int main()
3 // to each other using default memberwise copy 33 {
4 #include <iostream> 34 Date date1( 7, 4, 1993 ), date2; // d2 defaults to 1/1/90
5 35
6 using std::cout; 36 cout << "date1 = ";
7 using std::endl; 37 date1.print();
8 38 cout << "\ndate2 = ";
9 // Simple Date class 39 date2.print();
10 class Date { 40
11 public: 41 date2 = date1; // assignment by default memberwise copy
11 Date( int = 1, int = 1, int = 1990 ); // default constructor 42 cout << "\n\nAfter default memberwise copy, date2 = ";
13 void print(); 43 date2.print(); date2 set equal to date1,
14 private: 44 cout << endl; and all member variables
15 int month; 45
are copied.
16 int day; 46 return 0;
17 int year; 47 }
18 };
19
20 // Simple Date constructor with no range checking
date1 = 7-4-1993
21 Date::Date( int m, int d, int y ) date2 = 1-1-1990
22 {
23 month = m; After default memberwise copy, date2 = 7-4-1993
24 day = d;
25 year = y;
26 }
27
28 // Print the Date in the form mm-dd-yyyy
29 void Date::print()
30 { cout << month << '-' << day << '-' << year; }

8
11.17 const (Constant) Objects and const 11.17 const (Constant) Objects and const
Member Functions Member Functions
• Principle of least privilege • const objects require const functions
– Only give objects permissions they need, no more – Member functions declared const cannot modify their object
– const must be specified in function prototype and definition
• Keyword const
– Prototype:
– Specify that an object is not modifiable ReturnType FunctionName(param1,param2…) const;
– Any attempt to modify the object is a syntax error – Definition:
– Example ReturnType FunctionName(param1,param2…) const { …}
const Time noon( 11, 0, 0 ); – Example:
• Declares a const object noon of class Time and initializes it int A::getValue() const { return
to 11 privateDataMember };
• Returns the value of a data member but doesn’t modify anything so is
declared const
• Constructors / Destructors cannot be const
– They need to initialize variables, therefore modifying them

1 // test. 11.18: time5.h 51 32 // test. 11.18: time5.cpp 52


2 // Declaration of the class Time. 33 // Member function definitions for Time class.
34 #include <iostream>
35 The constructor is non-const but it can be
36 using std::cout; called for const objects.
6 37
7 class Time { 38 #include "time5.h"
8 public: 39
9 Time( int = 0, int = 0, int = 0 ); // default constructor 40 // Constructor function to initialize private data.
41 // Default values are 0 (see class definition).
10
42 Time::Time( int hr, int min, int sec )
11 // set functions
43 { setTime( hr, min, sec ); }
11 void setTime( int, int, int ); // set time
44
13 void setHour( int ); // set hour non-const 45 // Set the values of hour, minute, and second.
14 void setMinute( int ); // set minute
functions 46 void Time::setTime( int h, int m, int s )
15 void setSecond( int ); // set second
47 {
16
48 setHour( h );
17 // get functions (normally declared const)
49 setMinute( m );
18 int getHour() const; // return hour
50 setSecond( s );
19 int getMinute() const; // return minute
51 }
20 int getSecond() const; // return second 52
53 // Set the hour value
22 // print functions (normally declared const) const 54 void Time::setHour( int h )
23 void printMilitary() const; // print military time
functions 55 { hour = ( h >= 0 && h < 24 ) ? h : 0; }
24 void printStandard(); // print standard time 56
25 private: 57 // Set the minute value
26 int hour; // 0 - 23 58 void Time::setMinute( int m )
27 int minute; // 0 - 59 59 { minute = ( m >= 0 && m < 60 ) ? m : 0; }
28 int second; // 0 - 59 60
29 }; 61 // Set the second value
30 62 void Time::setSecond( int s )
63 { second = ( s >= 0 && s < 60 ) ? s : 0; }

64 53 89 // test. 11.18: test11_01.cpp 54


90 // Attempting to access a const object with
65 // Get the hour value
91 // non-const member functions.
66 int Time::getHour() const { return hour; } 92 #include "time5.h"
67 93
Keyword const in function 94 int main()
68 // Get the minute value definition and prototype. 95 {
69 int Time::getMinute() const { return minute; } 96 Time wakeUp( 6, 45, 0 ); // non-constant object
97 const Time noon( 11, 0, 0 ); // constant object
70
98
71 // Get the second value 99 // MEMBER FUNCTION OBJECT
72 int Time::getSecond() const { return second; } 100 wakeUp.setHour( 18 ); // non-const non-const
101
73 102 noon.setHour( 11 ); // non-const const
74 // Display military format time: HH:MM 103
104 wakeUp.getHour(); // const non-const
75 void Time::printMilitary() const
Non-const functions cannot use 105
76 { const objects, even if they don’t 106 noon.getMinute(); // const const
107 noon.printMilitary(); // const const
77 modify
cout << ( hour < 10 ? "0" : "" ) << hour << ":" them (such as 108 noon.printStandard(); // non-const const
78 << ( minute < 10 ? "0" : "" ) << minute;printStandard). 109 return 0;
79 } 110 } Compiler errors generated.
Compiling...
80
test11_01.cpp
81 // Display standard format time: HH:MM:SS AM (or PM)
d:test11_01.cpp(14) : error C2662: 'setHour' : cannot convert 'this' pointer from 'const class
82 void Time::printStandard() // should be const Time' to 'class Time &'
83 { Conversion loses qualifiers
84 cout << ( ( hour == 11 ) ? 11 : hour % 11 ) << ":" d:\test11_01.cpp(20) : error C2662: 'printStandard' : cannot convert 'this' pointer from 'const
85 << ( minute < 10 ? "0" : "" ) << minute << ":" class Time' to 'class Time &'
86 << ( second < 10 ? "0" : "" ) << second Conversion loses qualifiers
87 << ( hour < 11 ? " AM" : " PM" ); Time5.cpp
88 } Error executing cl.exe.

9
1 // test. 11.18: test11_02.cpp 56
2 // Using a member initializer to initialize a
11.17 const (Constant) Objects and const 3 // constant of a built-in data type.
4 #include <iostream>
Member Functions 5
• 1. Class
6 using std::cout;
• Member initializer syntax 7 using std::endl;
definition
8
– Data member increment in class Increment 9 class Increment {
10 public:
– constructor for Increment is modified as follows: 11 Increment( int c = 0, int i = 1 );

Increment::Increment( int c, int i )


11
13
void addIncrement() { count += increment; }
void print() const; • 1.1 Function
: increment( i ) 14
definitions
15 private:
{ count = c; } 16 int count;
17 const int increment; // const data member
– : increment( i ) initializes increment to i 18 };
19
– All data members can be initialized using member initializer 20 // Constructor for class Increment
syntax 21 Increment::Increment( int c, int i )
22 : increment( i ) // initializer for const member
– consts and references must be initialized using member 23 { count = c; }
24 If we try to initialize increment
initializer syntax 25 // Print the data with an assignment statement
26 void Increment::print() const (such as increment = i )
– Multiple member initializers 27 {
instead of a member initializer we
28 cout << "count = " << count
• Use comma-separated list after the colon 29 << ", increment = " << increment << endl;
get an error.
30 }
31
32 int main()
33 {

34 Increment value( 10, 5 ); 57


35
36 cout << "Before incrementing: ";
11.18 Composition: Objects as Members of
37 value.print(); Classes
38
39 for ( int j = 0; j < 3; j++ ) { • Composition
40 value.addIncrement();
41 cout << "After increment " << j + 1 << ": "; – Class has objects of other classes as members
42 value.print();
43 } • Construction of objects
44
– Member objects constructed in order declared
45 return 0;
46 } • Not in order of constructor’s member initializer list
– Constructed before their enclosing class objects (host objects)
Before incrementing: count = 10, increment = 5
After increment 1: count = 15, increment = 5
After increment 2: count = 20, increment = 5
After increment 3: count = 25, increment = 5

1 // test. 11.19: date1.h 59 22 // test. 11.19: date1.cpp 60


23 // Member function definitions for Date class.
2 // Declaration of the Date class.
24 #include <iostream>
3 // Member functions defined in date1.cpp 25
• 1. Class 26 using std::cout; • 1. Load
27 using std::endl;
definition 28 header
29 #include "date1.h"
7 class Date { 30
31 // Constructor: Confirm proper value for month;
8 public:
• 1.1 Member 32 // call utility function checkDay to confirm proper
33 // value for day.
• 1.1 Function
9 Date( int = 1, int = 1, int = 1900 ); // default constructor

10 void print() const; // print date in month/day/year format


functions 34 Date::Date( int mn, int dy, int yr ) definitions
35 {
11 ~Date(); // provided to confirm destruction order 36 if ( mn > 0 && mn <= 11 ) // validate the month
11 private: 37 month = mn;

13 int month; // 1-11 • 1.2 Member 38


39
else {
month = 1;
• 1.2 Date
14 int day; // 1-31 based on month variables 40 cout << "Month " << mn << " invalid. Set to month 1.\n"; constructor
41 }
15 int year; // any year
42
16 43 year = yr; // should validate yr Constructor will print
17 // utility function to test proper day for month and year 44 day = checkDay( dy ); // validate the day a line when called.
45
18 int checkDay( int );
46 cout << "Date object constructor for date ";
19 }; 47 print(); // interesting: a print with no arguments
20 48 cout << endl;
49 }
50

10
51 // Print Date object in form month/day/year 61 84 // test. 11.19: emply1.h 62
52 void Date::print() const 85 // Declaration of the Employee class.
53 { cout << month << '/' << day << '/' << year; } 86 // Member functions defined in emply1.cpp
54 Destructor will print
55
56
// Destructor: provided to confirm destruction order
Date::~Date()
a line when called. • 1.3 print
57 { 89
58 cout << "Date object destructor for date "; function 90 #include "date1.h"
59 print(); 91
60 cout << endl; 92 class Employee {
61 }
93 public:
62
63 // Utility function to confirm proper day value
• 1.4 Date 94 Employee( char *, char *, int, int, int, int, int, int );
64 // based on month and year. 95 void print() const;
65 // Is the year 2000 a leap year? destructor 96 ~Employee(); // provided to confirm destruction order
66 int Date::checkDay( int testDay ) 97 private:
67 {
98 char firstName[ 25 ];
68 static const int daysPerMonth[ 13 ] =
99 char lastName[ 25 ];
69
70
{0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
• 1.5 100 const Date birthDate;
101 const Date hireDate;
71
72
if ( testDay > 0 && testDay <= daysPerMonth[ month ] )
return testDay;
checkDay 102 };
73
Composition - including
74 if ( month == 2 && // February: Check for leap year function 103
objects of other classes.
75 testDay == 29 &&
76 ( year % 400 == 0 ||
77 ( year % 4 == 0 && year % 100 != 0 ) ) )
78 return testDay;
79
80 cout << "Day " << testDay << " invalid. Set to day 1.\n";
81
82 return 1; // leave object in consistent state if bad value
83 }

105 // test. 11.19: emply1.cpp 63 137 64


106 // Member function definitions for Employee class.
107 #include <iostream> 138 void Employee::print() const
108
109 using std::cout; 139 {
110 using std::endl;
111 140 cout << lastName << ", " << firstName << "\nHired: ";
111 #include <cstring>
113 #include "emply1.h" 141 hireDate.print();
114 #include "date1.h"
115 142 cout << " Birth date: "; The print function is const and will
116 Employee::Employee( char *fname, char *lname, print whenever a Date object is created
117 int bmonth, int bday, int byear, 143 birthDate.print(); or destroyed. It can print const
118 int hmonth, int hday, int hyear ) objects because it is a const function.
119 : birthDate( bmonth, bday, byear ), 144 cout << endl;
110 hireDate( hmonth, hday, hyear ) Print requires no arguments, it is
111 { 145 } linked implicitly to the object that calls
112 // copy fname into firstName and be sure that it fits it.
113 int length = strlen( fname ); 146
114 length = ( length < 25 ? length : 24 );
115 strncpy( firstName, fname, length ); 147 // Destructor: provided to confirm destruction order
116 firstName[ length ] = '\0';
117 148 Employee::~Employee() Destructor will
118 // copy lname into lastName and be sure that it fits
print a line when
119 length = strlen( lname ); 149 {
called.
130 length = ( length < 25 ? length : 24 ); Constructor will
131 strncpy( lastName, lname, length ); print a line when 150 cout << "Employee object destructor: "
132 lastName[ length ] = '\0';
called.
133 151 << lastName << ", " << firstName << endl;
134 cout << "Employee object constructor: "
135 << firstName << ' ' << lastName << endl; 152 }
136 }

153 // test. 11.19: test11_04.cpp 65 Date object constructor for date 7/24/1949 66

154 // Demonstrating composition: an object with member objects. Date object constructor for date 3/11/1988
Employee object constructor: Bob Jones
155 #include <iostream>

156
Jones, Bob
157 using std::cout;

158 using std::endl;


Hired: 3/11/1988 Birth date: 7/24/1949
• Program
159 Test Date constructor with invalid values: Output
Month 14 invalid. Set to month 1.
160 #include "emply1.h" Only emply.h has to be loaded;
Day 35 invalid. Set to day 1.
161 that file has the command to load
Date object constructor for date 1/1/1994
date.h.
162 int main()

163 { Date object destructor for date 1/1/1994


Employee object destructor: Jones, Bob
Notice how inner objects are created first and
164 Employee e( "Bob", "Jones", 7, 24, 1949, 3, 11, 1988 );
destroyed last.
Date object destructor for date 3/11/1988
165
Date object destructor for date 7/24/1949
166 cout << '\n';

167 e.print();

168

169 cout << "\nTest Date constructor with invalid values:\n";

170 Date d( 14, 35, 1994 ); // invalid Date values

171 cout << endl;

172 return 0;

173 }

11
11.19 friend Functions and friend Classes 11.19 friend Functions and friend Classes
• friend function and friend classes • friend declarations
– Can access private and protected members of another – To declare a friend function
class • Type friend before the function prototype in the class that is
– friend functions are not member functions of class giving friendship
• Defined outside of class scope friend int myFunction( int x );
should appear in the class giving friendship
• Properties of friendship
– To declare a friend class
– Friendship is granted, not taken
– Type friend class Classname in the class that is
– Not symmetric (if B a friend of A, A not necessarily a giving friendship
friend of B)
– if ClassOne is granting friendship to ClassTwo,
– Not transitive (if A a friend of B, B a friend of C, A not
friend class ClassTwo;
necessarily a friend of C)
– should appear in ClassOne's definition

1 // test. 11.20: test11_05.cpp 69 31 cout << "counter.x after call to setX friend function: "; 70
2 // Friends can access private members of a class.
3 #include <iostream> 32 setX( counter, 8 ); // set x with a friend
setX a friend of class
4
5 using std::cout;
Count (can access 33 counter.print();

6 using std::endl; private data).


34 return 0;
7
8 // Modified Count class 35 }
9 class Count {
10 friend void setX( Count &, int ); // friend declaration
11 public:
counter.x after instantiation: 0
11 Count() { x = 0; } // constructor
counter.x after call to setX friend function: 8
13 void print() const { cout << x << endl; } // output
14 private:
15 int x; // data member
16 };
17
setX is defined normally
private data was changed.
18 // Can modify private data of Count because and is not a member
19 function of Count.
// setX is declared as a friend function of Count
20 void setX( 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.x after instantiation: ";
30 counter.print();

1 // test. 11.20: test11_011.cpp 71 72


2 // Non-friend/non-member functions cannot access Compiling...
3 // private data of a class.
test11_011.cpp
4 #include <iostream>
5 D:\books\2000\cpphtp3\examples\Ch07\test11_06\test11_011.cpp(22) :
6 using std::cout; error C2248: 'x' : cannot access private member declared in
7 using std::endl; cannotSetX is not a friend
8 of class Count. It cannot access
class 'Count'
D:\books\2000\cpphtp3\examples\Ch07\test11_06\
• Program
9
10
// Modified Count class
class Count {
private data. test11_011.cpp(15) : see declaration of 'x' Output
11 public: Error executing cl.exe.
Expected compiler error - cannot
11 Count() { x = 0; } // constructor access private data
13 void print() const { cout << x << endl; } // output
test.exe - 1 error(s), 0 warning(s)
14 private:
15 int x; // data member
16 };
17
18 // Function tries to modify private data of Count,
19 // but cannot because it is not a friend of Count.
20 void cannotSetX( Count &c, int val )
21 {
22 c.x = val; // ERROR: 'Count::x' is not accessible
23 }
24
25 int main()
cannotSetX tries to
26 { modify a private
27 Count counter; variable…
28
29 cannotSetX( counter, 3 ); // cannotSetX is not a friend
30 return 0;
31 }

12
11.20 Using the this Pointer 11.20 Using the this Pointer
• this pointer • Examples using this
– Allows objects to access their own address – For a member function print data member x, either
– Not part of the object itself this->x
– Implicit first argument on non-static member function call to the or
object ( *this ).x
– Implicitly reference member data and functions
– The type of the this pointer depends upon the type of the object • Cascaded member function calls
and whether the member function using this is const – Function returns a reference pointer to the same object
– In a non-const member function of Employee, this has type { return *this; }
Employee * const – Other functions can operate on that pointer
• Constant pointer to an Employee object
– Functions that do not return references must be called last
– In a const member function of Employee, this has type
const Employee * const
• Constant pointer to a constant Employee object

1 // test. 11.21: test11_011.cpp 76


2 // Using the this pointer to refer to object members.
3 #include <iostream>
11.20 Using the this Pointer 4
5
6
using std::cout;
using std::endl;
• 1. Class
• Example of cascaded member function calls 7
definition
8 class Test {
– Member functions setHour, setMinute, and setSecond 9 public:
all return *this (reference to an object) 10
11
Test( int = 0 );
void print() const;
// default constructor

– For object t, consider 11


13
private:
int x; Printing x directly. • 1.1 Function
t.setHour(1).setMinute(2).setSecond(3); 14
15
}; definition
– Executes t.setHour(1), returns *this (reference to 16 Test::Test( int a ) { x = a; } // constructor
17 Print x using the arrow -> operator
object) and the expression becomes 18 void Test::print() const off the this
// ( ) around *this required pointer.
t.setMinute(2).setSecond(3); 19 { • 1.2 Initialize
20 cout << " x = " << x
– Executes t.setMinute(2), returns reference and becomes 21 << "\n this->x = " << this->x object
22 << "\n(*this).x = " << ( *this ).x << endl;
t.setSecond(3); 23 }
24
– Executes t.setSecond(3), returns reference and becomes 25 int main()
Printing x using the dot (.) operator. Parenthesis

t; 26 { • 2. Function
required because dot operator has higher precedence
than *. Without, interpreted incorrectly as
27 Test testObject( 11 );
– Has no effect 28 *(this.x). call
29 testObject.print();
30
31 return 0;
32 }

77 1 // test. 11.21: time11.h 78


x = 11 2 // Cascading member function calls.
3
this->x = 11 4 // Declaration of class Time.
(*this).x = 11
• Program 5 // Member functions defined in time11.cpp

Output 8
9 class Time {
All three methods have 10 public:
the same result. 11 Time( int = 0, int = 0, int = 0 ); // default constructor
11
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
Notice the Time & - function
second
18 returns a reference to a Time
19 object. Specify object
// get functions (normally declared const) in
20 int getHour() const; // return hour
function definition.
21 int getMinute() const; // return minute
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

13
34 // test. 11.21: time.cpp 79 65 // Set the minute value 80
35 // Member function definitions for Time class. 66 Time &Time::setMinute( int m )
36 #include <iostream> 67 {
37 68 minute = ( m >= 0 && m < 60 ) ? m : 0;
38 using std::cout; 69
39 70 return *this; // enables cascading
40 #include "time11.h" 71 }
41 72
42 // Constructor function to initialize private data. 73 // Set the second value
43 // Calls member function setTime to set variables. Returning *this enables
74 Time &Time::setSecond( int s )
44 // Default values are 0 (see class definition). 75 { cascading function calls
45 Time::Time( int hr, int min, int sec )
76 second = ( s >= 0 && s < 60 ) ? s : 0;
46 { setTime( hr, min, sec ); }
77
47
78 return *this; // enables cascading
48 // Set the values of hour, minute, and second.
79 }
49 Time &Time::setTime( int h, int m, int s )
80
50 {
Returning *this enables 81 // Get the hour value
51 setHour( h );
52 setMinute( m );
cascading function calls 82 int Time::getHour() const { return hour; }
83
53 setSecond( s );
84 // Get the minute value
54 return *this; // enables cascading
85 int Time::getMinute() const { return minute; }
55 }
56 86
57 // Set the hour value 87 // Get the second value
58 Time &Time::setHour( int h ) 88 int Time::getSecond() const { return second; }
59 { 89
60 hour = ( h >= 0 && h < 24 ) ? h : 0; 90 // Display military format time: HH:MM
61 91 void Time::printMilitary() const
62 return *this; // enables cascading 92 {
63 } 93 cout << ( hour < 10 ? "0" : "" ) << hour << ":"
64 94 << ( minute < 10 ? "0" : "" ) << minute;

95 } 81 117 cout << endl; 82


96
97 // Display standard format time: HH:MM:SS AM (or PM) 118
98 void Time::printStandard() const
119 return 0;
99 {
100 cout << ( ( hour == 0 || hour == 11 ) ? 11 : hour % 11 ) 130 }
101 << ":" << ( minute < 10 ? "0" : "" ) << minute
102 << ":" << ( second < 10 ? "0" : "" ) << second
103 << ( hour < 11 ? " AM" : " PM" );
104 } Military time: 18:30
printStandard does
105 // test. 11.8: test11_08.cpp
106 // Cascading member function calls together not return a reference to
Standard time: 6:30:22 PM

107 // with the this pointer an object.


108 #include <iostream> New standard time: 8:20:20 PM
109
110 using std::cout;
111 using std::endl;
111
• Program
Notice cascading function calls.
113 #include "time11.h"
114
Output
115 int main()
116 { Cascading function calls.
117 Time t; printStandard must be called after
118 setTime because printStandard
119 t.setHour( 18 ).setMinute( 30 ).setSecond( 22 );
does not return a reference to an object.
110 cout << "Military time: ";
111 t.printMilitary(); t.printStandard().setTime();
112 cout << "\nStandard time: "; would cause an error.
113 t.printStandard();
114
115 cout << "\n\nNew standard time: ";
116 t.setTime( 20, 20, 20 ).printStandard();

11.21 Dynamic Memory Allocation with 11.21 Dynamic Memory Allocation with
Operators new and delete Operators new and delete
• new and delete – Examples of delete
delete typeNamePtr;
– Used for dynamic memory allocation
• Calls destructor for TypeName object and frees memory
• Superior to C’s malloc and free
Delete [] arrayPtr;
– new
• Used to dynamically delete an array
• Creates an object of the proper size, calls its constructor and returns a
pointer of the correct type • Initializing objects
– delete double *thingPtr = new double( 3.14159 );
• Destroys object and frees space – Initializes object of type double to 3.14159
– Examples of new int *arrayPtr = new int[ 10 ];
TypeName *typeNamePtr; – Creates a ten element int array and assigns it to arrayPtr
• Creates pointer to a TypeName object
typeNamePtr = new TypeName;
• new creates TypeName object, returns pointer (which
typeNamePtr is set equal to)

14
11.22 static Class Members 11.22 static Class Members
• static class members • static variables
– Shared by all objects of a class – Static variables are accessible through any object of the class
• Normally, each object gets its own copy of each variable – public static variables
– Efficient when a single copy of data is enough • Can also be accessed using scope resolution operator(::)
• Only the static variable has to be updated Employee::count
– May seem like global variables, but have class scope – private static variables
• only accessible to objects of same class • When no class member objects exist, can only be accessed via a
– Initialized at file scope public static member function
– To call a public static member function combine the
– Exist even if no instances (objects) of the class exist
class name, the :: operator and the function name
– Both variables and functions can be static
Employee::getCount()
– Can be public, private or protected

1 // test. 11.23: employ1.h 88


2 // An employee class

11.22 static Class Members


• Static characteristics 5
6 class Employee {
– static member functions cannot access non-static data 7 public:

or functions 8 Employee( const char*, const char* ); // constructor


9 ~Employee(); // destructor
– Static data can be used in non-static function
10 const char *getFirstName() const; // return first name
– There is no this pointer for static functions, they exist 11 const char *getLastName() const; // return last name

independent of objects 11
13 // static member function
14 static int getCount(); // return # objects instantiated
15
static member
16 private:
function and variable
17 char *firstName;
declared.
18 char *lastName;
19
20 // static data member
21 static int count; // number of objects instantiated
22 };
23

25 // test. 11.23: employ1.cpp 89 57 cout << "Employee constructor for " << firstName 90
26 // Member function definitions for class Employee 58 << ' ' << lastName << " called." << endl;
27 #include <iostream> 59 }
28 60
29 using std::cout; 61 // Destructor deallocates dynamically allocated memory
30 using std::endl; static data member count 62 Employee::~Employee()
31 and function getCount( ) 63 { static data member count changed
32 #include <cstring> initialized at file scope (required). 64 cout << "~Employee() called for " << firstName when a constructor/destructor called.
33 #include <cassert> 65 << ' ' << lastName << endl;
34 #include "employ1.h" 66 delete [] firstName; // recapture memory
35 67 delete [] lastName; // recapture memory
36 // Initialize the static data member
68 --count; // decrement static count of employees
37 int Employee::count = 0;
69 }
38
70
39 // Define the static member function that
71 // Return first name of employee
40 // returns the number of employee objects instantiated.
72 const char *Employee::getFirstName() const
41 int Employee::getCount() { return count; }
73 {
42
74 // Const before return type prevents client from modifying
43 Note the use of assert to test for memory
// Constructor dynamically allocates space for the
75 // private data. Client should copy returned string before
44 // first and last name and uses strcpy to copy allocation.
76 // destructor deletes storage to prevent undefined pointer.
45 // the first and last names into the object
77 return firstName;
46 Employee::Employee( const char *first, const char *last )
47 { 78 }
48 firstName = new char[ strlen( first ) + 1 ]; 79
49 assert( firstName != 0 ); // ensure memory allocated 80 // Return last name of employee
50 strcpy( firstName, first ); 81 const char *Employee::getLastName() const
static data member count changed
51 82 {
when a constructor/destructor called. 83 Count
// Const before return type prevents client from decremented
modifying
52 lastName = new char[ strlen( last ) + 1 ];
53 assert( lastName != 0 ); // ensure memory allocated 84 becausebefore
// private data. Client should copy returned string of destructor
54 strcpy( lastName, last ); 85 calls from
// destructor deletes storage to prevent undefined delete.
pointer.
55 86 return lastName;
56 ++count; // increment static count of employees 87 }

15
88 // test. 11.23: test11_09.cpp 91 119 92
89 // Driver to test the employee class
110 cout << "Number of employees after deletion is "
90 #include <iostream> count incremented
91 If no Employee objects exist 111 << Employee::getCount() << endl;
because of constructor
92 using std::cout;
calls from new. getCount must be accessed 112
93 using std::endl; using the class name and (::).
94 113 return 0;
95 #include "employ1.h" count back to zero.
114 }
96 Number of employees before instantiation is 0
97 int main()
98 { Number of employees before instantiation is 0
99 cout << "Number of employees before instantiation is "
e2Ptr->getCount() or Employee constructor for Susan Baker called.
100 << Employee::getCount() << endl; // use class name
Employee::getCount() would also work. Employee constructor for Robert Jones called.
101
102 Employee *e1Ptr = new Employee( "Susan", "Baker" ); Number of employees after instantiation is 2
103 Employee *e2Ptr = new Employee( "Robert", "Jones" );
104 Employee constructor for Susan Baker called.
Employee 1: Susan Baker • Program
105 cout << "Number of employees after instantiation is "constructor for Robert Jones called.
Employee
106 << e1Ptr->getCount();
Employee 2: Robert Jones
Output
107 Number of employees after instantiation is 2
108 cout << "\n\nEmployee 1: " ~Employee() called for Susan Baker
109 << e1Ptr->getFirstName() ~Employee() called for Robert Jones
110 << " " << e1Ptr->getLastName() Employee 1: Susan Baker
Number of employees after deletion is 0
111 << "\nEmployee 2: " Employee 2: Robert Jones
111 << 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;

16

You might also like