CP Lect 07 (This Pointer)
CP Lect 07 (This Pointer)
Computer Programming
This Pointer
Computer Programming 2
Computer Programming 3
Other functions can operate on that pointer Functions that do not return references must be called last
Computer Programming 4
Executes t.setHour(1), returns *this (reference to object) and the expression becomes
t.setMinute(2).setSecond(3);
Has no effect
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.7: fig07_07.cpp // Using the this pointer to refer to object members. #include <iostream> using std::cout; using std::endl; class Test { public: Test( int = 0 ); void print() const; private: int x; }; Test::Test( int a ) { x = a; }
// default constructor
Printing x directly.
void Test::print() const { cout << " x = " << x << "\n this->x = " << this->x << "\n(*this).x = " << ( *this ).x << endl; }
Print x using the arrow -> operator off the this pointer. // ( ) around *this required
// constructor
Printing x using the dot (.) operator. Parenthesis required because dot operator has higher precedence than *. Without, interpreted incorrectly as *(this.x).
x = 12 this->x = 12 (*this).x = 12
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 33
// Fig. 7.8: time6.h // Cascading member function calls. // Declaration of class Time. // Member functions defined in time6.cpp #ifndef TIME6_H #define TIME6_H class Time { public: Time( int = 0, int = 0, int = 0 ); // set functions Time &setTime( int, int, Time &setHour( int ); Time &setMinute( int ); Time &setSecond( int );
// default constructor
// set hour, minute, second hour minute Notice the Time & - function returns a second reference to a Time object. Specify
object in function definition. // get functions (normally declared const) int getHour() const; // return hour int getMinute() const; // return minute int getSecond() const; // return second // print functions (normally declared const) void printMilitary() const; // print military time void printStandard() const; // print standard time private: int hour; // 0 - 23 int minute; // 0 - 59 int second; // 0 - 59 }; #endif
34 35 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 64
// Fig. 7.8: time.cpp // Member function definitions for Time class. #include <iostream> using std::cout; #include "time6.h" // Constructor function to initialize private data. // Calls member function setTime to set variables. // Default values are 0 (see class definition). Time::Time( int hr, int min, int sec ) { setTime( hr, min, sec ); } // Set the values of hour, minute, and second. Time &Time::setTime( int h, int m, int s ) Returning *this enables cascading { function calls setHour( h ); setMinute( m ); setSecond( s ); return *this; // enables cascading } // Set the hour value Time &Time::setHour( int h ) { hour = ( h >= 0 && h < 24 ) ? h : 0; return *this; } // enables cascading
65 // Set the minute value 66 Time &Time::setMinute( int m ) 67 { 68 minute = ( m >= 0 && m < 60 ) ? m : 0;
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94
return *this; }
// enables cascading
// Set the second value Time &Time::setSecond( int s ) { second = ( s >= 0 && s < 60 ) ? s : 0; return *this; } // Get the hour value int Time::getHour() const { return hour; } // Get the minute value int Time::getMinute() const { return minute; } // Get the second value int Time::getSecond() const { return second; } // Display military format time: HH:MM void Time::printMilitary() const // enables cascading
{
cout << ( hour < 10 ? "0" : "" ) << hour << ":" << ( minute < 10 ? "0" : "" ) << minute;
95 } 96 97 // Display standard format time: HH:MM:SS AM (or PM) 98 void Time::printStandard() const 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 } printStandard does not 105 // Fig. 7.8: fig07_08.cpp return a reference to an 106 // Cascading member function calls together object. 107 // with the this pointer 108 #include <iostream> 109 110 using std::cout; 111 using std::endl; 112 Notice cascading function calls. 113 #include "time6.h" 114 115 int main() Cascading function calls. printStandard must be called after 116 { setTime because printStandard does not return a reference to 117 Time t; an object. 118 t.printStandard().setTime(); would cause an error. 119 t.setHour( 18 ).setMinute( 30 ).setSecond( 22 ); 120 cout << "Military time: "; 121 t.printMilitary(); 122 cout << "\nStandard time: "; 123 t.printStandard(); 124 125 cout << "\n\nNew standard time: "; 126 t.setTime( 20, 20, 20 ).printStandard();
return 0;
Military time: 18:30 Standard time: 6:30:22 PM New standard time: 8:20:20 PM
Computer Programming
Dynamic Memory Allocation with Operators new and delete new and delete
Used for dynamic memory allocation
Creates an object of the proper size, calls its constructor and returns a pointer of the correct type
delete
new creates TypeName object, returns pointer (which typeNamePtr is set equal to)
Computer Programming
Dynamic Memory Allocation with Operators new and delete Examples of delete
delete typeNamePtr;
Computer Programming
Computer Programming
When no class member objects exist, can only be accessed via a public static member function
To call a public static member function combine the class name, the :: operator and the function name Employee::getCount()
Computer Programming
1 2
3 #ifndef EMPLOY1_H
4 5 6 7 8 9 10 11 12 13 14 15 16 private: 17 18 19 20 21 22 }; 23 24 #endif // static data member static int count; // number of objects instantiated char *firstName; char *lastName; // static member function static int getCount(); // return # objects instantiated static member function and variable declared. class Employee { public: Employee( const char*, const char* ); ~Employee(); const char *getFirstName() const; const char *getLastName() const; // constructor #define EMPLOY1_H
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56
// Fig. 7.9: employ1.cpp // Member function definitions for class Employee #include <iostream> using std::cout; using std::endl; #include <cstring> #include <cassert> #include "employ1.h" // Initialize the static data member int Employee::count = 0; // Define the static member function that // returns the number of employee objects instantiated. int Employee::getCount() { return count; } Note // Constructor dynamically allocates space for the the use of assert to test for memory allocation. // first and last name and uses strcpy to copy // the first and last names into the object Employee::Employee( const char *first, const char *last ) { firstName = new char[ strlen( first ) + 1 ]; assert( firstName != 0 ); // ensure memory allocated static data member count changed when a strcpy( firstName, first ); constructor/destructor called. lastName = new char[ strlen( last ) + 1 ]; assert( lastName != 0 ); // ensure memory allocated strcpy( lastName, last ); ++count; // increment static count of employees
static data member count and function getCount( ) initialized at file scope (required).
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
cout << "Employee constructor for " << firstName << ' ' << lastName << " called." << endl; } // Destructor deallocates dynamically allocated memory Employee::~Employee() static data member count changed when a { cout << "~Employee() called for " << firstName constructor/destructor called. << ' ' << lastName << endl; delete [] firstName; // recapture memory delete [] lastName; // recapture memory --count; // decrement static count of employees } // Return first name of employee const char *Employee::getFirstName() const { // Const before return type prevents client from modifying // private data. Client should copy returned string before // destructor deletes storage to prevent undefined pointer. return firstName; } // Return last name of employee const char *Employee::getLastName() const { Count decremented // Const before return type prevents client from modifying because of destructor // private data. Client should copy returned string before calls from delete. // destructor deletes storage to prevent undefined pointer. return lastName; }
88 // Fig. 7.9: fig07_09.cpp 89 // Driver to test the employee class 90 #include <iostream> If no Employee objects exist 91 getCount must be accessed using the count incremented because of 92 using std::cout; class name and (::). constructor calls from new. 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 " e2Ptr->getCount() or Employee::getCount() would 100 << Employee::getCount() << endl; also work. class name // use 101 102 Employee *e1Ptr = new Employee( "Susan", "Baker" ); 103 Employee *e2Ptr = new Employee( "Robert", "Jones" employees after instantiation is 2 Number of ); 104 105 cout << "Number of employees after instantiation is " 106 << e1Ptr->getCount(); Employee constructor for Susan Baker called. 107 Employee constructor for Robert Jones called. 108 cout << "\n\nEmployee 1: " 109 << e1Ptr->getFirstName() 110 << " " << e1Ptr->getLastName() Employee 1: Susan Baker Employee 2: Robert Jones 111 << "\nEmployee 2: "
119 120 121 122 123 124 } return 0; count back to zero. cout << "Number of employees after deletion is " << Employee::getCount() << endl;
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
Computer Programming
Data elements added (pushed) onto the bottom and removed (popped) from top Last-in, first-out (LIFO) data structure Client does not care how stack is implemented, only wants LIFO data structure Abstract data types (ADTs)
Model real world objects
Computer Programming
Subscript range checking An arbitrary range of subscripts instead of having to start with 0 Array assignment Array comparison Array input/output Arrays that know their sizes Arrays that expand dynamically to accommodate more elements
Computer Programming
Maximizes performance
Provides mechanisms for creating and implementing a string abstract data type string class available in ANSI/ISO standard (Chapter 19)
Computer Programming
Queue ADT
Clients may not manipulate data structure directly Only queue member functions can access internal data
Computer Programming
Arrays, stacks, queues, trees and linked lists Iterator objects (iterators)
Object that returns the next item of a collection (or performs some action on the next item) Can have several iterators per container
Computer Programming
Proxy Classes
Proxy class
Used to hide implementation details of a class Class that knows only the public interface of the class being hidden Enables clients to use classs services without giving access to classs implementation
1 2
3
4 5 6 7 8 9 10 11 12 }; 13 // Fig. 7.10: interface.h 14 // Header file for interface.cpp 15 class Implementation; 16 17 class Interface { 18 19 20 21 22 23 24 25 public: Interface( int ); void setValue( int ); int getValue() const; ~Interface(); private: Implementation *ptr; // requires previous // forward declaration Proxy class Interface has same public interface as class Implementation. Only uses a pointer to class Implementation. This allows us to hide the implementation details. // same public interface as // class Implementation // forward class declaration private: int value; Forward class declaration. class Implementation { public: Implementation( int v ) { value = v; } void setValue( int v ) { value = v; } Implementation has private data int getValue() const { return value; } we want to hide.
26 };
27 28 29 30 31 32 33 34 35 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
// Fig. 7.10: interface.cpp // Definition of class Interface #include "interface.h" #include "implementation.h"
Interface::Interface( int v ) : ptr ( new Implementation( v ) ) { } // call Implementation's setValue function Implementation file v ); } void Interface::setValue( int v ) { ptr->setValue(interface.cpp contains
member functions for proxy class Interface. It is the only file // call Implementation's getValue function that has header file implementation.h, which } int Interface::getValue() const { return ptr->getValue(); contains class Implementation.
Interface::~Interface() { delete ptr; } // Fig. 7.10: fig07_10.cpp // Hiding a classs private data with a proxy class. #include <iostream>
interface.cpp is precompiled and given with the header file interface.h. The client cannot see the interactions between the proxy class and the proprietary class.
Only the header Interface.h no mention of class Implementation. The client never sees the private data.
cout << "Interface contains: " << i.getValue() << " before setValue" << endl; i.setValue( 10 ); cout << "Interface contains: " << i.getValue() << " after setValue" << endl; return 0; }