1 Chapter 7 Classes Part II Outline 7
- Slides: 69
1 Chapter 7: Classes Part II Outline 7. 1 7. 2 7. 3 7. 4 7. 5 7. 6 7. 7 7. 8 7. 9 7. 10 Introduction const (Constant) Objects and const Member Functions Composition: Objects as Members of Classes friend Functions and friend Classes Using the this Pointer Dynamic Memory Management with Operators new and delete static Class Members Data Abstraction and Information Hiding 7. 8. 1 Example: Array Abstract Data Type 7. 8. 2 Example: String Abstract Data Type 7. 8. 3 Example: Queue Abstract Data Type Container Classes and Iterators Proxy Classes 2003 Prentice Hall, Inc. All rights reserved.
7. 2 const (Constant) Objects and const Member Functions • Principle of least privilege – Only allow modification of necessary objects • Keyword const – Specify object not modifiable – Compiler error if attempt to modify const object – Example const Time noon( 12, 0, 0 ); • Declares const object noon of class Time • Initializes to 12 2003 Prentice Hall, Inc. All rights reserved. 2
7. 2 const (Constant) Objects and const Member Functions • const objects require const functions – Member functions declared const cannot modify their object – const must be specified in function prototype and definition • Prototype (after parameter list): Return. Type Function. Name(param 1, param 2…) const; • Definition (before left brace): Return. Type Function. Name(param 1, param 2…) const { …} • Example: int A: : get. Value() const { return private. Data. Member }; • 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 2003 Prentice Hall, Inc. All rights reserved. 3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 // Fig. 7. 1: time 5. h // Declaration of the class Time. // Member functions defined in time 5. cpp #ifndef TIME 5_H #define TIME 5_H Outline class Time { public: Time( int = 0, int = 0 ); // default constructor // set functions void set. Time( int, int ); // set time void set. Hour( int ); // set hour void set. Minute( int ); // set minute void set. Second( int ); // set second // get functions (normally declared const) int get. Hour() const; // return hour int get. Minute() const; // return minute int get. Second() const; // return second // print functions (normally declared const) void print. Military() const; // print military timeconst void print. Standard(); // print standard timefunctions private: int hour; // 0 - 23 int minute; // 0 - 59 non-const int second; // 0 - 59 functions }; #endif 2003 Prentice Hall, Inc. All rights reserved. 4
32 33 34 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 // Fig. 7. 1: time 5. cpp // Member function definitions for Time class. #include <iostream> using std: : cout; The constructor is non-const but Outline it can be called for const objects. #include "time 5. h" // Constructor function to initialize private data. // Default values are 0 (see class definition). Time: : Time( int hr, int min, int sec ) { set. Time( hr, min, sec ); } // Set the values of hour, minute, and second. void Time: : set. Time( int h, int m, int s ) { set. Hour( h ); set. Minute( m ); set. Second( s ); } // Set the hour value void Time: : set. Hour( int h ) { hour = ( h >= 0 && h < 24 ) ? h : 0; } // Set the minute value void Time: : set. Minute( int m ) { minute = ( m >= 0 && m < 60 ) ? m : 0; } // Set the second value void Time: : set. Second( int s ) { second = ( s >= 0 && s < 60 ) ? s : 0; } 2003 Prentice Hall, Inc. All rights reserved. 5
64 Outline 65 // Get the hour value 66 int Time: : get. Hour() const { return hour; } 67 68 // Get the minute value Keyword const in function definition and prototype. 69 int Time: : get. Minute() const { return minute; } 70 71 // Get the second value 72 int Time: : get. Second() const { return second; } 73 74 // Display military format time: HH: MM 75 void Time: : print. Military() const 76 77 78 Non-const functions cannot use { const objects, even if they don’t cout << ( hour < 10 ? "0" : "" ) << hour << ": " modify them (such as << ( minute < 10 ? "0" : "" ) << minute; print. Standard). 79 } 80 81 // Display standard format time: HH: MM: SS AM (or PM) 82 void Time: : print. Standard() // should be const 83 { 84 cout << ( ( hour == 12 ) ? 12 : hour % 12 ) << ": " 85 << ( minute < 10 ? "0" : "" ) << minute << ": " 86 << ( second < 10 ? "0" : "" ) << second 87 << ( hour < 12 ? " AM" : " PM" ); 2003 Prentice Hall, Inc. 88 } All rights reserved. 6
89 // Fig. 7. 1: fig 07_01. cpp 90 // Attempting to access a const object with 91 // non-const member functions. 92 #include "time 5. h" 93 94 int main() 95 { 96 Time wake. Up( 6, 45, 0 ); // non-constant object 97 const Time noon( 12, 0, 0 ); // constant object 98 99 // MEMBER FUNCTION OBJECT 100 wake. Up. set. Hour( 18 ); // non-const 101 102 noon. set. Hour( 12 ); // non-const const 103 104 wake. Up. get. Hour(); // const non-const 105 106 noon. get. Minute(); // const 107 noon. print. Military(); // const 108 noon. print. Standard(); // non-const const 109 return 0; Compiler 110 } Compiling. . . Fig 07_01. cpp d: fig 07_01. cpp(14) : error C 2662: 'set. Hour' : cannot convert 'this' pointer from 'const class Time' to 'class Time &' Conversion loses qualifiers d: fig 07_01. cpp(20) : error C 2662: 'print. Standard' : cannot convert 'this' pointer from 'const class Time' to 'class Time &' Conversion loses qualifiers Time 5. cpp Error executing cl. exe. test. exe - 2 error(s), 0 warning(s) Outline errors generated. 2003 Prentice Hall, Inc. All rights reserved. 7
7. 2 const (Constant) Objects and const Member Functions • Member initializer syntax – Data member const increment in class Increment – constructor for Increment is modified as follows: Increment: : Increment( int c, int i ) : count( c ), increment( i ) {/* empty body */ } – : increment( i ) initializes increment to i – Multiple member initializers: • Use comma-separated list after the colon – Can be used for • All data members – Must be used for: • consts and references • Member objects, base class portion (later) 2003 Prentice Hall, Inc. All rights reserved. 8
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 // Fig. 7. 2: fig 07_02. cpp Declare increment // Using a member initializer to initialize a // constant of a built-in data type. data member. #include <iostream> as const Member initializer consists of data member name (increment) followed by parentheses containing initial value (c). Initialization is executed before body of constructor using std: : cout; using std: : endl; class Increment { public: Increment( int c = 0, int i = 1 ); void add. Increment() { count += increment; } void print() const; private: int count; const increment; // const data member }; Outline Member initializer syntax must be used for const data member increment. Member initializer syntax can data // Constructor for class Increment be used for non-const Increment: : Increment( int c, int i ) member count. : increment( i ), count( c ) // initializer for const member { /* empty body */ } // Print the data void Increment: : print() const { cout << "count = " << count << ", increment = " << increment << endl; } If we try to initialize increment with an assignment statement (such as increment = i ) instead of a member initializer we get an error. 2003 Prentice Hall, Inc. All rights reserved. 9
45 46 47 int main() { Increment value( 10, 5 ); 48 49 50 cout << "Before incrementing: "; value. print(); 51 52 53 54 55 56 for ( int j = 0; j < 3; j++ ) { value. add. Increment(); cout << "After increment " << j + 1 << ": "; value. print(); } 57 58 return 0; 59 60 } // end main Outline fig 07_04. cpp (3 of 3) fig 07_04. cpp output (1 of 1) 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 2003 Prentice Hall, Inc. All rights reserved. 10
Compiler Errors when not Initializing Properly 22 23 24 private: int count; const increment; // const data member 25 26 }; // end class Increment 27 28 29 30 31 32 33 34 Declare increment as const data member. // constructor Attempting to modify const Increment: : Increment( int c, int i ) data member increment { // Constant member 'increment' is not initialized count = c; // allowed because count is not constant results in error. Outline fig 07_05. cpp (2 of 3) increment = i; // ERROR: Cannot modify a const object Not using member initializer } // end Increment constructor syntax to initialize const data member increment results in error. D: cpphtp 4_examplesch 07Fig 07_03. cpp(30) : error C 2758: 'increment' : must be initialized in constructor base/member Attempting to modify const initializer list data member increment D: cpphtp 4_examplesch 07Fig 07_03. cpp(24) : results in error. see declaration of 'increment' D: cpphtp 4_examplesch 07Fig 07_03. cpp(32) : error C 2166: l-value specifies const object 2003 Prentice Hall, Inc. All rights reserved. 11
7. 3 Composition: Objects as Members of Classes • Composition – Class has objects of other classes as members • Construction of objects – Member objects constructed in order declared • Not in order of constructor’s member initializer list • Constructed before enclosing class objects (host objects) – From the Inside Out • Destruction of objects – Member objects destroyed in inverse order of their creation – From Outside In 2003 Prentice Hall, Inc. All rights reserved. 12
1 2 3 4 5 // Fig. 7. 6: date 1. h // Date class definition. // Member functions defined in date 1. cpp #ifndef DATE 1_H #define DATE 1_H 6 7 class Date { 8 9 10 11 12 Outline Note no constructor with a parameter of type Date. public: Date( int = 1, int = 1900 ); // default constructor Recall compiler provides void print() const; // print date in month/day/year format default copy constructor. ~Date(); // provided to confirm destruction order 13 14 15 16 17 private: int month; // 1 -12 (January-December) int day; // 1 -31 based on month int year; // any year 18 19 20 // utility function to test proper day for month and year int check. Day( int ) const; 21 22 }; // end class Date 23 24 #endif date 1. h (1 of 1) 2003 Prentice Hall, Inc. All rights reserved. 13
1 2 3 // Fig. 7. 7: date 1. cpp // Member-function definitions for class Date. #include <iostream> 4 5 6 using std: : cout; using std: : endl; 7 8 9 // include Date class definition from date 1. h #include "date 1. h" 10 11 12 13 14 15 16 // constructor confirms proper value for month; calls // utility function check. Day to confirm proper value for day Date: : Date( int mn, int dy, int yr ) { if ( mn > 0 && mn <= 12 ) // validate the month = mn; 17 18 19 20 21 else { // invalid month set to 1 month = 1; cout << "Month " << mn << " invalid. Set to month 1. n" ; } 22 23 24 year = yr; // should validate yr day = check. Day( dy ); // validate the day Outline date 1. cpp (1 of 3) 25 2003 Prentice Hall, Inc. All rights reserved. 14
26 27 28 29 // output Date object to show when its constructor is called cout << "Date object constructor for date " ; print(); cout << endl; 30 31 } // end Date constructor 32 33 34 35 36 { cout << month << '/' << day << '/' << year; Outline No arguments; each member Output to show timing of function contains implicit constructors. handle to object on which it // print Date object in form month/day/year operates. void Date: : print() const 37 38 } // end function print 39 40 41 42 43 44 45 46 47 Output to show timing of // output Date object to show when its destructor is called Date: : ~Date() destructors. { cout << "Date object destructor for date " ; print(); cout << endl; } // end destructor ~Date date 1. cpp (2 of 3) 48 2003 Prentice Hall, Inc. All rights reserved. 15
49 50 51 52 53 54 // utility function to confirm proper day value based on // month and year; handles leap years, too int Date: : check. Day( int test. Day ) const { static const int days. Per. Month[ 13 ] = { 0, 31, 28, 31, 30, 31 }; 55 56 57 58 // determine whether test. Day is valid for specified month if ( test. Day > 0 && test. Day <= days. Per. Month[ month ] ) return test. Day; 59 60 61 62 63 64 // February 29 check for leap year if ( month == 2 && test. Day == 29 && ( year % 400 == 0 || ( year % 4 == 0 && year % 100 != 0 ) ) ) return test. Day; 65 66 cout << "Day " << test. Day << " invalid. Set to day 1. n" ; 67 68 return 1; // leave object in consistent state if bad value 69 70 } // end function check. Day Outline date 1. cpp (3 of 3) 2003 Prentice Hall, Inc. All rights reserved. 16
1 2 3 4 5 // Fig. 7. 8: employee 1. h // Employee class definition. // Member functions defined in employee 1. cpp. #ifndef EMPLOYEE 1_H #define EMPLOYEE 1_H 6 7 8 // include Date class definition from date 1. h #include "date 1. h" 9 10 class Employee { 11 12 13 14 public: Employee( const char *, const Date &, const Date & ); 15 16 17 void print() const; ~Employee(); // provided to confirm destruction order 18 19 20 21 22 23 private: char first. Name[ 25 ]; char last. Name[ 25 ]; const Date birth. Date; // composition: member object const Date hire. Date; // composition: member object 24 25 }; // end class Employee Outline 17 employee 1. h (1 of 2) Using composition; Employee object contains Date objects as data members. 2003 Prentice Hall, Inc. All rights reserved.
26 27 #endif 1 2 3 // Fig. 7. 9: employee 1. cpp // Member-function definitions for class Employee. #include <iostream> 4 5 6 using std: : cout; using std: : endl; 7 8 #include <cstring> // strcpy and strlen prototypes 9 10 11 #include "employee 1. h" // Employee class definition #include "date 1. h" // Date class definition Outline 18 employee 1. h (2 of 2) employee 1. cpp (1 of 3) 12 2003 Prentice Hall, Inc. All rights reserved.
13 14 15 16 17 18 19 20 21 22 23 24 25 26 // constructor uses member initializer list to pass initializer // values to constructors of member objects birth. Date and // hire. Date [Note: This invokes the so-called "default copy // constructor" which the C++ compiler provides implicitly. ] Employee: : Employee( const char *first, const char *last, const Date &date. Of. Birth, const Date &date. Of. Hire ) : birth. Date( date. Of. Birth ), // initialize birth. Date hire. Date( date. Of. Hire ) // initialize hire. Date { Member initializer syntax to // copy first into first. Name and be sure that it fits initialize Date data members int length = strlen( first ); length = ( length < 25 ? length : 24 ); birth. Date and hire. Date; compiler uses strncpy( first. Name, first, length ); first. Name[ length ] = '