870 likes | 1.02k Views
Chapter 14. More About Classes. Instance and Static Members. Instance variable : A member variable in a class Each object has its own copy static variable: One variable shared among all objects of a class static member function : Can be used to access static member variable
E N D
Chapter 14 More About Classes
Instance and Static Members • Instance variable: • A member variable in a class • Each object has its own copy • static variable: • One variable shared among all objects of a class • static member function: • Can be used to access static member variable • Can be called before any objects are defined Chapter 14
Member (Instance)Variables Object W1, W2 Chapter 14
Member Variable is Static Chapter 14
Budget.h – Program #ifndef BUDGET_H #define BUDGET_H class Budget { private: static double corpBudget; double divBudget; public: Budget(void) { divBudget = 0; } void addBudget( double b) { divBudget += b; corpBudget += b; } double getDivBudget(void) { return divBudget; } double getCorpBudget(void) { return corpBudget; } }; // Budget double Budget::corpBudget = 0; // Static member #endif Chapter 14
testBudget.cpp – Program #include <iostream> #include <iomanip> #include "Budget.h" using namespace std; int main(void) { int count; const int NUMDIVISIONS = 4; Budget divisions[NUMDIVISIONS]; for (int count = 0; count < NUMDIVISIONS; count++) { double bud; cout << "Enter the budget request for division "; cout << (count + 1) << ": "; cin >> bud; divisions[count].addBudget(bud); } // for Chapter 14
testBudget.cpp – Program cout << fixed << showpoint < setprecision(2); cout << "\nHere are the division budget requests:\n"; for ( int count = 0; count < NUMDIVISIONS; count++) { cout << "\tDivision " << (count + 1) << "\t$ "; cout << divisions[count].getDivBudget() << endl; } // for cout << "\tTotal Budget Requests:\t$ "; cout << divisions[0].getCorpBudget() << endl; return 0; } // main Chapter 14
testBudget.cpp – Output Enter the budget request for Division 1: 100000 [Enter] Enter the budget request for Division 2: 200000 [Enter] Enter the budget request for Division 3: 300000 [Enter] Enter the budget request for Division 4: 400000 [Enter] Here are the division budget requests: Division 1 $ 100000.00 Division 2 $ 200000.00 Division 3 $ 300000.00 Division 4 $ 400000.00 Total Budget Requests: $ 1000000.00 Chapter 14
Static Member Functions • Declared with static before return type: static int getVal ( ) { return valueCount; } • Can only access static member data • Can be called independent of objects: cout << "There are " << IntVal::getVal( ) << " objects\n"; Chapter 14
A New Budget.h – Program #ifndef BUDGET_H #define BUDGET_H class Budget {private: static double corpBudget; double divBudget; public: Budget(void) { divBudget = 0; } void addBudget( double b) { divBudget += b; corpBudget += b; } double getDivBudget(void) { return divBudget; } double getCorpBudget(void) { return corpBudget; } static void mainOffice( double ); }; // Budget #endif Chapter 14
Budget.cpp – Program #include "budget.h" double Budget::corpBudget = 0; void Budget::mainOffice( double moffice) { corpBudget += moffice; } // Budget::mainOffice Chapter 14
testBudget.cpp – Program #include <iostream> #include <iomanip> #include "Budget.h" using namespace std; int main(void) {int count; double mainOfficeRequest const int NUMDIVISIONS = 4; cout << "Enter the main office's budget request: "; cin >> mainOfficeRequest; Budget::mainOffice(mainOfficeRequest); Budget divisions[NUMDIVISIONS]; for (count = 0; count < NUMDIVISIONS; count++) { doublebudgetAmount; cout << "Enter the budget request for division "; cout << (count + 1) << ": "; cin >> budgetAmount; divisions[count].addBudget(budgetAmount); } // for Chapter 14
testBudget.cpp – Program cout << fixed << showpoint << setprecision(2); cout << "\nHere are the division budget requests:\n"; for (int count = 0; count < NUMDIVISIONS; count++) { cout << "\tDivision " << (count + 1) << "\t$ "; cout << divisions[count].getDivBudget() << endl; } // for cout << "\tTotal Budget Requests (including main office):\t$ "; cout << divisions[0].getCorpBudget() << endl; return 0; } // main Chapter 14
testBudget.cpp – Output Enter the main office's budget request: 100000 [Enter] Enter the budget request for Division 1: 100000 [Enter] Enter the budget request for Division 2: 200000 [Enter] Enter the budget request for Division 3: 300000 [Enter] Enter the budget request for Division 4: 400000 [Enter] Here are the division budget requests: Division 1 $ 100000.00 Division 2 $ 200000.00 Division 3 $ 300000.00 Division 3 $ 400000.00 Total Requests (including main office): $ 1100000.00 Chapter 14
Friends of Classes • Friend • A function or class that is not a member of a class, but has access to private members of the class • A friend function can be a stand-alone function or a member function of another class • It is declared a friend of a class with friend keyword in the function prototype Chapter 14
Friend Function Declarations • Stand-alone function: friend void setAVal ( intVal &, int ); • Declares setAVal function be a friend of this class • Member function of another class: friend void SomeClass::setNum( int num ); • setNum function from Someclass class is a friend of this class Chapter 14
Friend Classes • As mentioned before, it is possible to make an entire class a friend of another class. class FriendClass { … }; // FriendClass class NewClass { public: friend class FriendClass; // declares entire class (Friendclass) as a friend of this class … }; // NewClass Chapter 14
Memberwise Assignment • The assignment operator (=) may be used to assign one object to another, or to initialize one object with another object’s data • Thus v2 = v1; means that each member of one object is copied to its counterpart in the other object • Use when class is defined: IntVal v3 = v2; Chapter 14
Copy Constructors • A copy constructor is a special constructor, called whenever a new object is created and initialized with another object’s data • Assume the class PersonInfo has a member variable as follows: name char *. • Consider the following declarations: • PersonInfo person1( "Maria Jones-Tucker", 25 ); • PersonInfo person2 = person1; Chapter 14
PersonInfo person1("Maria Jones-Tucker", 25); Maria Jones-Tucker namepointer Dynamically allocated memory Chapter 14
PersonInfo person2 = person1; Dynamically allocated memory Maria Jones-Tucker person1’snamepointer Both objects’ name members point to the same section of memory person2’snamepointer Chapter 14
Programmer Defined Copy Constructor • Allows us to solve the problem with pointers PersonInfo::PersonInfo( PersonInfo &obj ) { name = new char[strlen( obj.name ) + 1]; strcpy( name, obj.name ); age = obj.age; } // PersonInfo::PersonInfo • Copy constructor takes a reference parameter to an object of the class Chapter 14
“Ann” “Jane” info1 info2 name name Programmer Defined Copy Constructor • Consider the following: PersonInfo info1( "Ann", 5 ); PersonInfo info2 = info1; info2.setName( "Jane" ); Chapter 14
Using const Parameters • Because copy constructors are required to use reference parameters, they have access to their argument’s data PersonInfo::PersonInfo( PersonInfo &obj ) • They should not be allowed to change the parameters, therefore, it is a good idea to make the parameter const so it can’t be modified PersonInfo::PersonInfo( const PersonInfo &obj ) Chapter 14
The Default Copy Constructor • If a class doesn’t have a copy constructor, C++ automatically creates a default copy constructor • The default copy constructor performs a memberwise assignment Chapter 14
Operator Overloading • C++ allows you to redefine how standard operators work when used with class objects Chapter 14
Overloading the = Operator • This is done with a member function such as: void operator = ( const PersonInfo &right ); • This member function is called as follows: • person2 = person1; • person2.operator = ( person1 ); • Note that the parameter, right, is declared as a reference, for efficiency purposes • The reference prevents the compiler form making a copy of the object being passed into the function • Also note that the parameter is declared constant so the function does not accidentally change the contents of the argument Chapter 14
Operator Overload – Program #include <iostream> #include <cstring> using namespace std; class PersonInfo { private: char *name; int age; public: PersonInfo(char *n, int a){ name = new char[strlen(n) + 1]; strcpy(name, n); age = a; } PersonInfo(const PersonInfo &obj) // Copy constructor { name = new char[strlen(obj.name) + 1]; strcpy(name, obj.name); age = obj.age; } ~PersonInfo(void){ delete [] name; } char *getName(void){ return name; } int getAge(void){ return age; } void operator=(const PersonInfo &right) { delete [] name;name = new char[strlen(right.name) + 1]; strcpy(name, right.name); age = right.age; } }; // PersonInfo Chapter 14
Operator Overload – Program int main(void) { PersonInfo jim("Jim Young", 27),bob("Bob Faraday", 32), clone = jim; cout << "The Jim Object contains: " << jim.getName(); cout << ", " << jim.getAge() << endl; cout << "The Bob Object contains: " << bob.getName(); cout << ", " << bob.getAge() << endl; cout << "The Clone Object contains: " << clone.getName(); cout << ", " << clone.getAge() << endl; cout << "Now the clone will change to Bob and "; cout << "Bob will change to Jim.\n"; clone = bob; bob = jim; cout << "The Jim Object contains: " << jim.getName(); cout << ", " << jim.getAge() << endl; cout << "The Bob Object contains: " << bob.getName(); cout << ", " << bob.getAge() << endl; cout << "The Clone Object contains: " << clone.getName(); cout << ", " << clone.getAge() << endl; return 0; } // main Chapter 14
Operator Overload – Output The Jim Object contains: Jim Young, 27 The Bob Object contains: Bob Faraday, 32 The Clone Object contains: Jim Young, 27 Now the clone will change to Bob and Bob will change to Jim. The Jim Object contains: Jim Young, 27 The Bob Object contains: Jim Young, 27 The Clone Object contains: Bob Faraday, 32 Chapter 14
The = Operator’s Return Value • If the operator= function returns a void, as in the previous example, then multiple assignment statements won’t work • To enable a statement such as person3 = person2 = person1; you must have the following prototype: PersonInfo operator= (const PersonInfo &Right); Chapter 14
The this Pointer • this is a special built-in pointer that is available in any member function • this contains the address of the object that called the member function • The thispointer is passed as a hidden argument to all non-static member functions Chapter 14
Use of this pointer • This refers to the class itself. Chapter 14
You can use “this” to refer to class variables. Class MyInt { private: int a; public: void MyInt(int a) { // The 'this' pointer is used to get access to class variable “a” rather than local variable “a” this->a = a; } void doit(){ } }; Chapter 14
You can use “this” even when it is the not required Class MyInt { private: int a; public: void MyInt(int a) { this->a = a; doit(); // both of these calls to the same thing. “this” is understood this->doit(); // both of these calls to the same thing. “this” is understood } void doit(){ cout << “just Called contructor”;} } }; Chapter 14
Sometimes you need a name for yourself. “this” is that name Class MyInt { private: int a; public: void MyInt(int a) { this->a = a; } MyInt* returnBigger(MyInt * other){ if (other->a > a) return other; return this; // If I am the bigger, return me! } }; Chapter 14
The this Pointer • PersonInfo person1, person2; • cout << person1.getName( ) << endl; • What does the this pointer point to? • cout << person2.getName( ) << endl; • What does the this pointer point to? Chapter 14
Using this – Program #include <iostream> #include <cstring> using namespace std; class PersonInfo { private: char *name; int age; public: PersonInfo(char *n, int a) { name = new char[strlen(n)+ 1]; strcpy(name, n); age = a; } Chapter 14
Using this – Program PersonInfo(const PersonInfo &obj) // Copy constructor { name = new char[strlen(obj.name)+ 1]; strcpy(name, obj.name); age = obj.age; } ~PersonInfo(void){ delete [] name; } char *getName(void){ return name; } int getAge(void){ return age; } const PersonInfo operator=(const PersonInfo &right) { delete [] name; name = new char[strlen(right.name) + 1]; strcpy(name, right.name); age = right.age; return *this; } }; // PersonInfo Chapter 14
Using this – Program int main(void) { PersonInfo jim("Jim Young", 27),bob("Bob Faraday", 32), clone = jim; cout << "The Jim Object contains: " << jim.getName(); cout << ", " << jim.getAge() << endl; cout << "The Bob Object contains: " << bob.getName(); cout << ", " << bob.getAge() << endl; cout << "The Clone Object contains: " << clone.getName(); cout << ", " << clone.getAge() << endl; cout << "Now the clone and Bob will change to Jim.\n"; clone = bob = jim; cout << "The Jim Object contains: " << jim.getName(); cout << ", " << jim.getAge() << endl; cout << "The Bob Object contains: " << bob.getName(); cout << ", " << bob.getAge() << endl; cout << "The Clone Object contains: " << clone.getName(); cout << ", " << clone.getAge() << endl; return 0; } // main Chapter 14
Using this – Output The Jim Object contains: Jim Young, 27 The Bob Object contains: Bob Faraday, 32 The Clone Object contains: Jim Young, 27 Now the clone and Bob will change to Jim. The Jim Object contains: Jim Young, 27 The Bob Object contains: Jim Young, 27 The Clone Object contains: Jim Young, 27 Chapter 14
Issues of Operator Overloading • You can change an operator’s entire meaning when you overload it – don’t • You cannot change the number of operands taken by an operator • For example, the = symbol must always be a binary operator • Likewise, ++ and -- must always be unary operators • The following operators cannot overloaded • ?: . .* :: sizeof Chapter 14
Operators That can be Overloaded Chapter 14
feetinch.h – Program #ifndef FEETINCHES_H #define FEETINCHES_H class FeetInches { private: int feet; int inches; void simplify(void); public: FeetInches(int f = 0, int i = 0) { feet = f; inches = i; simplify(); } void setFeet( int f ) { feet = f; } Chapter 14
feetinch.h – Program void setInches(int i){ inches = i;simplify();} int getFeet(void){ return feet; } int getInches(void){ return inches; } FeetInches operator + (const FeetInches &); FeetInches operator - (const FeetInches &); FeetInches operator ++ ( void ); // Prefix ++ FeetInches operator ++ ( int ); // Postfix ++ bool operator > ( const FeetInches & ); bool operator < ( const FeetInches & ); bool operator == ( const FeetInches & ); friend ostream &operator << ( ostream & , const FeetInches & ); friend istream &operator >> ( istream &, const FeetInches & ); }; // FeetInches #endif Chapter 14
FeetInches • Why didn’t we overload the assignment ( = ) operator? Chapter 14
simplify • 3 feet 14 inches • 4 feet 2 inches • 5 feet -2 inches • 4 feet 10 inches Chapter 14
feetinc.cpp – Program #include <cstdlib> #include "feetinch.h" void FeetInches::simplify(void) { if (inches >= 12) { feet += (inches / 12); inches %= 12; } // if else if (inches < 0) { feet -= ((abs(inches) / 12) + 1); inches = 12 - (abs(inches) % 12); } // else } // FeetInches::simplify Chapter 14
feetinc.cpp – Program FeetInches FeetInches::operator+(const FeetInches &right) { FeetInches temp; temp.inches = inches + right.inches; temp.feet = feet + right.feet; temp.simplify(); return temp; } // FeetInches::operator + FeetInches FeetInches::operator-(const FeetInches &right) { FeetInches temp; temp.inches = inches - right.inches; temp.feet = feet - right.feet; temp.simplify(); return temp; } // FeetInches::operator - Chapter 14
feetmain.cpp – Program #include <iostream> #include "feetinc2.h“ using namespace std; int main(void) { FeetInches first, second, third; int f, i; cout << "Enter a distance in feet and inches: "; cin >> f >> i; first.setData(f, i); cout << "Enter another distance in feet and inches: "; cin >> f >> i; second.setData(f, i); third = first + second; cout << "First + Second = "; cout << third.getFeet() << " feet, "; cout << third.getInches() << " inches.\n"; third = first - second; cout << "First - Second = "; cout << third.getFeet() << " feet, "; cout << third.getInches() << " inches.\n"; return 0; } // main Chapter 14