350 likes | 367 Views
CS 222 Object Oriented Programming Using C++. A DEABER Look at Classes PART 2. Imam Muhammad bin Saud University. College of Computer Science and Information. Contents. Friend Functions Overloading Constructors Dynamic Initialization Assigning Objects The This Pointer
E N D
CS 222 Object Oriented Programming Using C++ A DEABER Look at Classes PART 2 Imam Muhammad bin Saud University. College of Computer Science and Information
Contents • Friend Functions • Overloading Constructors • Dynamic Initialization • Assigning Objects • The This Pointer • const (Constant) Objects and const Member Functions • Static Member Functions
Friend Functions • A non-member function that can access the private members of a class • Defined outside class’s scope • To make a function a friend function • Include its prototype in the class • Precede it with the friend keyword
Friend Function Example #include <iostream> usingnamespace std; class myclass { int a, b; public: myclass(int i, int j) { a=i; b=j; } friendint sum(myclass x); }; // sum() is not a member function // of any class. int sum(myclass x) { /* Because sum() is a friend of myclass, it can directly access a and b. */ return x.a + x.b; } int main() { myclass n(3, 4); cout << sum(n); return0; }
Why Friend Functions • Overloading certain types of operators • Simplify the creation of some input/output functions • To access 2 or more classes with less overhead • Friend functions maybe stand-alone functions or member functions of other classes
Friend Function Example #include <iostream> using namespace std; constint IDLE=0; constint INUSE=1; class C2; // forward declaration class C1 { int status; // IDLE if off, INUSE//…// if on screen public: void set_status(int state); friendint idle(C1 a, C2 b); }; class C2 { int status; // IDLE if off, INUSE//… //if on screen public: void set_status(int state); friendint idle(C1 a, C2 b); }; void C1::set_status(int state) { status = state; } void C2::set_status(int state) { status = state; } // idle( ) is a friend of C1 and C2. int idle(C1 a, C2 b) { if(a.status || b.status) return0; elsereturn1; } int main(){ C1 x; C2 y; x.set_status(IDLE); y.set_status(IDLE); if(idle(x, y)) cout<<"Screen Can Be Used"; else cout << "Pop-up In Use.\n"; x.set_status(INUSE); if(idle(x, y)) cout<<"Screen Can Be Used"; else cout << "Pop-up In Use.\n"; return 0;}
A member function of another class as a friend function. Example #include <iostream> usingnamespace std; constint IDLE=0; constint INUSE=1; class C2; // forward declaration class C1 { int status; // IDLE if off, INUSE if // ... //on screen public: void set_status(int state); int idle(C2 b); //now a member of C1 }; class C2 { int status; // ... public: void set_status(int state); friendint C1::idle(C2 b); }; void C1::set_status(int state) { status = state; } void C2::set_status(int state) { status = state; } // idle() is member of C1, but friend of C2. int C1::idle(C2 b) { if(status || b.status) return0; elsereturn1; } int main() { C1 x; C2 y; x.set_status(IDLE); y.set_status(IDLE); if(x.idle(y)) cout<<"Screen Can Be Used.\n"; else cout << "Pop-up In Use.\n"; x.set_status(INUSE); if(x.idle(y)) cout<<"Screen Can Be Used.\n"; else cout << "Pop-up In Use.\n"; return0;}
Friend Classes • We can make all member functions of class ClassTwo friends of class ClassOne • Place declaration of form friend class ClassTwo; in ClassOne definition
Overloading Constructors • Constructors are loaded to provide more flexibility. • Enables programmers to construct objects in the most natural manner relative to their specific use. • It is important when creating a library of classes for some one else to use • Just like function overloading • The compiler is able to call the correct version of each constructor. • The compiler uses the type and/or number of arguments as its guide to determine which constructor to call. • Thus constructors must differ in the type and/or of their parameters.
Overloading Constructors Example #include <iostream> #include <cstdlib> #include <ctime> usingnamespace std; class timer{ int seconds; public: // seconds specified as a string timer(char *t){ seconds = atoi(t);} // seconds specified as integer timer(int t) { seconds = t; } // time in minutes and seconds timer(int min, int sec) { seconds = min*60 + sec; } void run(); } ; void timer::run() { clock_t t1; t1 = clock(); while( (clock()/CLOCKS_PER_SEC - t1/CLOCKS_PER_SEC) < seconds ) cout << "\a";// ring the bell } int main() { timer a(10), b("20"), c(1, 10); a.run(); // count 10 seconds b.run(); // count 20 seconds c.run(); // count 1 minute, 10 seconds return0; } clock() returns the number of system clock ticks since the program began running
Dynamic Initialization • In C++ both global and local variables can be initialized at run time (Dynamic Initialization) • E.g. int n = strlen(str); • Objects like simple variables can be initialized dynamically
Dynamic Initialization • In C++ both global and local variables can be initialized at run time (Dynamic Initialization) • E.g. int n = strlen(str); • Objects like simple variables can be initialized dynamically
Dynamic Initialization Example #include <iostream> #include <cstdlib> #include <ctime> usingnamespace std; class timer{ int seconds; public: // seconds specified as a string timer(char *t){ seconds = atoi(t);} // seconds specified as integer timer(int t) { seconds = t; } // time in minutes and seconds timer(int min, int sec) { seconds = min*60 + sec; } void run(); } ; void timer::run() { clock_t t1; t1 = clock(); while( (clock()/CLOCKS_PER_SEC - t1/CLOCKS_PER_SEC) < seconds ) cout << "\a";// ring the bell } int main() { timer a(10); a.run(); cout << "Enter number of seconds: "; char str[80]; cin >> str; timer b(str); // initialize at run time b.run(); cout << "Enter minutes and seconds: "; int min, sec; cin >> min >> sec; timer c(min, sec); // initialize at run time c.run(); return0; }
Using the this Pointer • Each time a member function is invoked, it is automatically passed a pointer, called this, to the object that has invoked it. • The this pointer is an implicit parameter to all member functions. • Friend functions do not have a this pointer. Because only member functions have a this pointer • The following example is trivial no one would actually use the this pointer in this way.
this Pointer Example #include <iostream> usingnamespace std; class cl { int i; public: void load_i(int val) { this->i = val; } // same as i = val int get_i() { return this->i; } // same as return i } ; int main() { cl o; o.load_i(100); cout << o.get_i(); return 0; }
const (Constant) Objects and const Member Functions • 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
const (Constant) Objects and const Member Functions • const member functions • Member functions for const objects must also be const • Cannot modify object • Specify const in both prototype and definition • Prototype • After parameter list • Definition • Before beginning left brace • Constructors and destructors • Cannot be const • Must be able to modify objects • Constructor • Initializes objects • Destructor • Performs termination housekeeping
const Example class Time { public: Time( int = 0, int = 0, int = 0 ); // default constructor // set functions void setTime( int, int, int ); // set time void setHour( int ); // set hour void setMinute( int ); // set minute void setSecond( int ); // set second // 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 printUniversal() const; // print universal time void printStandard(); // print standard time
const Example // set second value void Time::setSecond( int s ) { second = ( s >= 0 && s < 60 ) ? s : 0; } // end function setSecond // return hour value int Time::getHour() const { return hour; } // end function getHour // return minute value int Time::getMinute() const { return minute; } // end function getMinute
Static Class Members • Each object of a class contains its own data • However a static variable is shared by all objects of the class • If no other initialization is present all static data is initialized to zero • May seem like global variables, but have class scope • Only accessible to objects of same class • Exists even if no objects of the class exist • Can be public, private or protected
Static Class Members • Accessing static class variables • Accessible through any object of class • publicstatic variables • Can also be accessed using binary scope resolution operator(::) Employee::count • privatestatic variables • When no class member objects exist • Can only be accessed via publicstatic member function • To call publicstatic member function combine class name, binary scope resolution operator (::) and function name Employee::getCount() • static member functions • Cannot access non-static data or functions • No this pointer for static functions • static data members and static member functions exist independent of objects
Static Class Members Example class Employee { public: Employee(constchar *, constchar * ); ~Employee(); constchar *getFirstName() const; constchar *getLastName() const; // static member function // return # objects instantiated staticint getCount(); private: char *firstName; char *lastName; // static data member // number of objects instantiated staticint count; }; // end class Employee Employee::count = 0; int Employee::getCount() { return count; } Employee::Employee( constchar *first, constchar *last ) { firstName = new char[strlen(first)+1 ]; strcpy( firstName, first ); lastName = new char[strlen(last) + 1 ]; strcpy( lastName, last ); ++count; } Employee::~Employee() { delete [] firstName; delete [] lastName; --count; }
Static Class Members Example int main() { cout << "Number of employees before instantiation is " << Employee::getCount() << endl; // use class name Employee *e1Ptr = new Employee( "Susan", "Baker" ); Employee *e2Ptr = new Employee( "Robert", "Jones" ); cout << "Number of employees after instantiation is " << e1Ptr->getCount(); delete e1Ptr; // recapture memory e1Ptr = 0; // disconnect pointer from free-store space delete e2Ptr; // recapture memory e2Ptr = 0; // disconnect pointer from free-store space cout << "Number of employees after deletion is " << Employee::getCount() << endl; return0; } // end main
Copying objects • C++ defines two distinct situations in which the value of one object is given to another: • Assignment. • Initialization, which can occur three ways: • When an object is used to initialize another object in a declaration statement. • When an object is passed as a parameter to a function. • When a temporary object is created for use as a return value by a function.
Assigning objects • If both objects are of the same class, then they can be assigned to each other • In this case a bitwise copy of the 1st object’s data is copied to the 2nd. myclass ob1, ob2; ob2= ob1;
Initialization • Initialization of an object by another object in declaration statement. myclass x=y; // y explicitly initializes x • Passing objects to functions func(y); // y is passed as a parameter • Returning objects y = func(); //y receiving a returned object.
Passing objects to functions • Objects are passed to functions using normal C++ call by value. • a copy of the object, not the actual object is passed. • changes made to the object inside the function do not affect the object used as the argument to the function. • In this case no problem ( see example1 in the next page). • Problem: in passing objects with constructors and destructors.()
Example1:Passing objects to functions #include <iostream> usingnamespace std; class OBJ { int i; public: void set_i(int x) { i = x; } void out_i() { cout << i << " "; } }; void f(OBJ x) { x.out_i(); // outputs 10 x.set_i(100); // this affects only local copy x.out_i(); // outputs 100 } int main() { OBJ o; o.set_i(10); f(o); o.out_i(); // still outputs 10, value of unchanged return0; }