Presentation is loading. Please wait.

Presentation is loading. Please wait.

More About Classes. C++: Classes & Objects -2 2 Instance and Static Members Each instance of a class has its own copies of the class’s instance (member)

Similar presentations


Presentation on theme: "More About Classes. C++: Classes & Objects -2 2 Instance and Static Members Each instance of a class has its own copies of the class’s instance (member)"— Presentation transcript:

1 More About Classes

2 C++: Classes & Objects -2 2 Instance and Static Members Each instance of a class has its own copies of the class’s instance (member) variables  Objects box1 and box2 of class Rectangle each have their own values for length and width static variable: one member 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 instantiated

3 C++: Classes & Objects -2 3 static member variable Contents of Tree. h 1 // Tree class 2 class Tree 3 { 4 private: 5 static int objectCount; // Static member variable. 6 public: 7 // Constructor 8 Tree() 9 { objectCount++; } 10 11 // Accessor function for objectCount 12 int getObjectCount() const 13 { return objectCount; } 14 }; 15 16 // Definition of the static member variable, written 17 // outside the class. 18 int Tree::objectCount = 0; Static member declared here. Static member defined here.

4 C++: Classes & Objects -2 4

5 5 Three Instances of the Tree Class, Only One objectCount Variable

6 C++: Classes & Objects -2 6 static member function Declared with static before return type: static int getObjectCount() { return objectCount; } Static member functions can only access static member data Can be called independent of objects: int num = Tree::getObjectCount();

7 C++: Classes & Objects -2 7 Modified Version of Tree. h 1 // Tree class 2 class Tree 3 { 4 private: 5 static int objectCount; // Static member variable. 6 public: 7 // Constructor 8 Tree() 9 { objectCount++; } 10 11 // Accessor function for objectCount 12 static int getObjectCount() 13 { return objectCount; } 14 }; 15 16 // Definition of the static member variable, written 17 // outside the class. 18 int Tree::objectCount = 0; Now we can call the function like this: cout << "There are " << Tree::getObjectCount()<< " objects.\n";

8 C++: Classes & Objects -2 8 Budget Class version 1 Budget class gathers budget information from all the divisions of a company The static member, corpBudget, holds the overall corporate budget The function addBudget adds the passed amount to the division total as well as the corporate total

9 C++: Classes & Objects -2 9 Budget version 1 In main, we call getCorpBudget by specifying an object of the Budget class: divisions[0].getCorpBudget()  Note that a static method can not specify const You can also call the function as Budget::getCorpBudget() but then the function would have to be static and could not be const

10 C++: Classes & Objects -2 10 Budget version 1 Budget version 1 #ifndef BUDGET_H #define BUDGET_H class Budget { private: static double corpBudget; // Static member double divisionBudget; // Instance member public: Budget() { divisionBudget = 0; } void addBudget(double b) { divisionBudget += b; corpBudget += b; } double getDivisionBudget() const { return divisionBudget; } double getCorpBudget() const // not defined static otherwise could not be const { return corpBudget; } // therefore requires an object to be called }; // Definition of static member variable corpBudget double Budget::corpBudget = 0; #endif

11 C++: Classes & Objects -2 11 Budget version 1 #include #include "Budget.h" using namespace std; int main() { int count; // Loop counter const int NUM_DIVISIONS = 4; // Number of divisions Budget divisions[NUM_DIVISIONS]; // Array of Budget objects // Get the budget requests for each division. for (count = 0; count < NUM_DIVISIONS; count++) { double budgetAmount; cout << "Enter the budget request for division "; cout << (count + 1) << ": "; cin >> budgetAmount; divisions[count].addBudget(budgetAmount); } // Display the budget requests and the corporate budget. cout << fixed << showpoint << setprecision(2); cout << "\nHere are the division budget requests:\n"; for (count = 0; count < NUM_DIVISIONS; count++) { cout << "\tDivision " << (count + 1) << "\t$ "; cout << divisions[count].getDivisionBudget() << endl; } cout << "\tTotal Budget Requests:\t$ "; cout << divisions[0].getCorpBudget() << endl; return 0; }

12 C++: Classes & Objects -2 12 Budget Class version 2 Here a static function, mainOffice, is found  This allows the inclusion of a budget for the main office in addition to the individual divisions  The function can be called even before any objects of the Budget class have been instantiated

13 C++: Classes & Objects -2 13 Budget version 2 #ifndef BUDGET_H #define BUDGET_H class Budget { private: static double corpBudget; // Static member variable double divisionBudget; // Instance member variable public: Budget() { divisionBudget = 0; } void addBudget(double b) { divisionBudget += b; corpBudget += b; } double getDivisionBudget() const { return divisionBudget; } double getCorpBudget() const { return corpBudget; } static void mainOffice(double); // Static member function }; #endif

14 C++: Classes & Objects -2 14 Budget version 2 THIS IS FILE BUDGET.CPP #include "Budget.h" // Definition of corpBudget static member variable double Budget::corpBudget = 0; //********************************************************** // Definition of static member function mainOffice. * // This function adds the main office's budget request to * // the corpBudget variable. * //********************************************************** void Budget::mainOffice(double moffice) { corpBudget += moffice; }

15 C++: Classes & Objects -2 15 Budget version 2 #include #include "Budget.h" using namespace std; int main() { int count; // Main office budget request double mainOfficeRequest; const int NUM_DIVISIONS = 4;// # of divisions //Get the main office's budget request. //No instances of Budget class have been defined cout << "Enter the main office's budget: "; cin >> mainOfficeRequest; Budget::mainOffice(mainOfficeRequest); // An array of Budget objects. Budget divisions[NUM_DIVISIONS]; // Get the budget requests for each division. for (count = 0; count < NUM_DIVISIONS; count++) { double budgetAmount; cout << "Enter the division budget request "; cout << (count + 1) << ": "; cin >> budgetAmount; divisions[count].addBudget(budgetAmount); } // Display corporate and division budgets cout << fixed << showpoint<< setprecision(2); cout << "\nHere are the division budget requests:\n"; for (count=0; count<NUM_DIVISIONS; count++) { cout<<"\tDivision "<< (count+1)<< "\t$"; cout<<divisions[count].getDivisionBudget()<< endl; } cout << "\tTotal Budget Requests:\t$ "; cout << divisions[0].getCorpBudget()<< endl; return 0; }

16 C++: Classes & Objects -2 16 Budget version 2 What would you need to do in order to store the amount of the main office budget request as a static number and then print it out at the end of the report before the division budgets?

17 C++: Classes & Objects -2 17 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 must be declared a friend of a class with friend keyword in the function prototype of the class granting it access

18 C++: Classes & Objects -2 18 friend Function Declarations friend Function Declarations Stand-alone function: friend void setAVal(intVal&, int); // declares setAVal function to 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

19 C++: Classes & Objects -2 19 friend Function Declarations In the following example, the addBudget function of class AuxilliaryOffice has been declared a friend in the Budget class The auxiliary office (perhaps in another country) makes a separate budget request which must be added to the overall corporate budget  The friend declaration tells the compiler that the function is to be granted access to Budget’s private members In Auxil.h there is a forward declaration of the Budget class  This tells the compiler that a class named Budget will be declared later in the program. This is needed because the compiler will process Auxil.h before it processes the Budget class declaration

20 C++: Classes & Objects -2 20 Budget.h version 3 #ifndef BUDGET_H #define BUDGET_H #include "Auxil.h" // Budget class declaration class Budget { private: static double corpBudget; // Static member variable double divisionBudget; // Instance member variable public: Budget() { divisionBudget = 0; } void addBudget(double b) { divisionBudget += b; corpBudget += b; } double getDivisionBudget() const { return divisionBudget; } double getCorpBudget() const { return corpBudget; } // Static member function static void mainOffice(double); // Friend function friend void AuxiliaryOffice::addBudget(double, Budget &); }; #endif

21 C++: Classes & Objects -2 21 Budget.cpp version 3 #include "Budget.h" double Budget::corpBudget = 0; // Definition of static member variable //********************************************************** // Definition of static member function mainOffice. * // This function adds the main office's budget request to * // the corpBudget variable. * //********************************************************** void Budget::mainOffice(double moffice) { corpBudget += moffice; }

22 C++: Classes & Objects -2 22 Auxil.h Auxil.cpp #ifndef AUXIL_H #define AUXIL_H // Forward declaration of Budget class class Budget; // Aux class declaration class AuxiliaryOffice { private: double auxBudget; public: AuxiliaryOffice() { auxBudget = 0; } double getDivisionBudget() const { return auxBudget; } void addBudget(double, Budget &); }; #endif #include "Auxil.h" #include "Budget.h" //********************************************************* // Definition of member function mainOffice. // This function is declared a friend by the Budget class. // It adds the value of argument b to the static corpBudget // member variable of the Budget class. //********************************************************* void AuxiliaryOffice::addBudget(double b, Budget &div) { auxBudget += b; div.corpBudget += b; }

23 C++: Classes & Objects -2 23 Main.cpp part 1 #include #include "Budget.h" using namespace std; int main() { int count; // Loop counter double mainOfficeRequest; // Main office budget request const int NUM_DIVISIONS = 4; // Number of divisions // Get the main office's budget request. cout << "Enter the main office's budget request: "; cin >> mainOfficeRequest; Budget::mainOffice(mainOfficeRequest); Budget divisions[NUM_DIVISIONS]; // Array of Budget objects. AuxiliaryOffice auxOffices[4]; // Array of AuxiliaryOffice // Get the budget requests for each division and their auxiliary offices. for (count = 0; count < NUM_DIVISIONS; count++) { double budgetAmount; // To hold input // Get the request for the division office. cout << "Enter the budget request for division "; cout << (count + 1) << ": "; cin >> budgetAmount; divisions[count].addBudget(budgetAmount);

24 C++: Classes & Objects -2 24 Main.cpp part 2 // Get the request for the auxiliary office. cout << "Enter the budget request for that division's\n"; cout << "auxiliary office: "; cin >> budgetAmount; auxOffices[count].addBudget(budgetAmount, divisions[count]); } // Display the budget requests and the corporate budget. cout << fixed << showpoint << setprecision(2); cout << "\nHere are the division budget requests:\n"; for (count = 0; count < NUM_DIVISIONS; count++) { cout << "\tDivision " << (count + 1) << "\t\t$"; cout << divisions[count].getDivisionBudget() << endl; cout << "\tAuxiliary office:\t$"; cout << auxOffices[count].getDivisionBudget() << endl << endl; } cout << "Total Budget Requests:\t$ "; cout << divisions[0].getCorpBudget() << endl; return 0; }

25 C++: Classes & Objects -2 25 friend Class Declarations friend Class Declarations It is possible to make an entire class a friend of another class. The Budget class could make the Auxilliary Office class its friend by declaring friend class AuxilliaryOffice; In practice it is best to declare as friends only those functions that must have access to the private members of the class rather than an entire class In general: class FriendClass {... }; class NewClass { public: friend class FriendClass; … };

26 C++: Classes & Objects -2 26 Memberwise Assignment Can use = to assign one object to another, or to initialize an object with an object’s data Copies member to member. e.g., instance2 = instance1; means: copy all member values from instance1 and assign to the corresponding member variables of instance2 Use at initialization: Rectangle r2 = r1;

27 C++: Classes & Objects -2 27

28 C++: Classes & Objects -2 28

29 C++: Classes & Objects -2 29 Copy Constructors Special constructor used when a newly created object is initialized to the data of another object of same class Default copy constructor copies field-to-field Default copy constructor works fine in many cases

30 C++: Classes & Objects -2 30 Copy Constructors Problem: what if object contains a pointer? #include 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() { delete [] name; } const char *getName() { return name; } int getAge() { return age; } };

31 C++: Classes & Objects -2 31 Copy Constructors A potential problem with this class lies with the pointer member The constructor dynamically allocates a section of memory and copies a string to it PersonInfo person1(“John Smith”,30); If we perform the assignment PersonInfo person2 = person1; person2’s constructor is not called so a separate section of memory is not allocated for person2’s name member

32 C++: Classes & Objects -2 32 Copy Constructors Both pointers will point to the same address If either of the two objects change the string, it will be reflected in both objects If one object is destroyed, the remaining object’s pointer will still reference this section of memory although it should no longer be used person1’s name pointer person2’s name pointer John Smith Dynamically allocated memory

33 C++: Classes & Objects -2 33 Copy Constructors If you include a method in the class void setName(char *n) { strcpy(name, n); } and then include person1.setName(“Ira R”); in the main program, both objects will again have the same name if you invoke the function getName() for person1 and person2

34 C++: Classes & Objects -2 34 Copy Constructors What we really want is to create a copy of the dynamically allocated memory and have person2’s pointer point to it This is accomplished by using a copy constructor When the assignment operator is used to initialize person2 with the contents of person1, person1’s object is passed as an argument to person2’s object’s copy constructor For original object PersonInfo(char *n, int a) { name = new char[strlen(n) + 1]; strcpy(name, n); age = a; } For copy object PersonInfo(PersonInfo & obj) { name = new char[strlen(obj.name) + 1]; strcpy(name, obj.name); age = obj.age; }

35 C++: Classes & Objects -2 35 Copy Constructors Because copy constructor's are required to use reference parameters, they have access to their argument’s data Since the purpose of the copy constructor is to make a copy of the argument, there is no reason the constructor should modify the argument’s data Thus, it is a good idea to specify the keyword const in the parameter list PersonInfo(const PersonInfo & obj)

36 C++: Classes & Objects -2 36 Operator Overloading Operators such as =, +, and others can be redefined when used with objects of a class The name of the function for the overloaded operator is operator followed by the operator symbol, e.g., operator+ to overload the + operator, and operator= to overload the = operator Prototype for the overloaded operator goes in the declaration of the class that is overloading it Overloaded operator function definition goes with other member functions The / operator performs two types of division: floating point and integer  If one of the operands is of floating point type, the result will be floating point.  If both of the operands are integer, the result is an integer with the fractional remainder discarded

37 C++: Classes & Objects -2 37 Operator Overloading Prototype: void operator=(const SomeClass &rval) Operator is called via object on left side return type function name parameter for object on right side of operator

38 C++: Classes & Objects -2 38 Operator Function Overloading #include class PersonInfo { private: char *name; int age; public: // Constructor PersonInfo(char *n, int a) { name = new char[strlen(n) + 1]; strcpy(name, n); age = a; } // Copy Constructor PersonInfo(const PersonInfo &obj) { name = new char[strlen(obj.name) + 1]; strcpy(name, obj.name); age = obj.age; } // Destructor ~PersonInfo() { delete [] name; } // Accessor functions const char *getName() { return name; } int getAge() { return age; } // Overloaded = operator void operator=(const PersonInfo &right) { delete [] name; name = new char[strlen(right.name)+1]; strcpy(name, right.name); age = right.age; } }; Because the operator function is a member of the PersonInfo class, the function will be executed only when the object on the left side is of the class

39 C++: Classes & Objects -2 39 Invoking an Overloaded Operator Operator can be invoked as a member function: object1.operator=(object2); person2.operator=(person1); It can also be used in more conventional manner: object1 = object2; person2 = person1; Run PersonInfoOverloadObject project

40 C++: Classes & Objects -2 40 Invoking an Overloaded Operator // Create and initialize the jim object. PersonInfo jim("Jim Young", 27); // Create and initialize the bob object. PersonInfo bob("Bob Faraday", 32); // Create the clone object and initialize with jim. PersonInfo clone = jim; // Assign bob to clone. //Now the clone will change to bob and //bob will change to jim clone = bob; // Call overloaded = operator bob = jim; // Call overloaded = operator 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

41 C++: Classes & Objects -2 41 = Operator’s Return Value Return type the same as the left operand supports notation like: object1 = object2 = object3;  a=b=c; The expression b=c causes c to be assigned to b and then returns the value of c. The return value is stored in a. This requires the object’s overloaded = operator to have a valid return type Function declared as follows: const SomeClass operator=(const someClass &rval) const PersonInfo operator=(const PersonInfo & right) In function, include as last statement: return *this; which returns the value of a dereferenced pointer this

42 C++: Classes & Objects -2 42 = Operator’s Return Value // Create and initialize the jim object. PersonInfo jim("Jim Young", 27); // Create and initialize the bob object. PersonInfo bob("Bob Faraday", 32); // Create the clone object and initialize with jim. PersonInfo clone = jim; // Assign jim to bob and clone. clone = bob = jim; // Call overloaded = operator The jim Object contains: Jim Young, 27 The bob Object contains: Jim Young, 27 The clone Object contains: Jim Young, 27

43 C++: Classes & Objects -2 43 The this Pointer this : predefined pointer available to a class’s member functions Always points to the instance (object) of the class whose function is being called Is passed as a hidden argument to all non- static member functions Can be used to access members that may be hidden by parameters with same name

44 C++: Classes & Objects -2 44 this Pointer Example class SomeClass { private: int num; public: void setNum(int num) { this->num = num; }... };

45 C++: Classes & Objects -2 45 Another Example of Returning a Value Overloaded operator can return a value class Point2d { public: double operator-(const point2d &right) { return sqrt(pow((x-right.x),2) + pow((y-right.y),2)); }... private: int x, y; }; Point2d point1(2,2), point2(4,4); // Compute and display distance between 2 points. cout << point2 – point1 << endl; // displays 2.82843

46 C++: Classes & Objects -2 46 Notes on Overloaded Operators Can change meaning of an operator Cannot change the number of operands of the operator  = symbol is always a binary operator  ++ and – are unary operators Only certain operators can be overloaded. Cannot overload the following operators: ?:..* :: sizeof

47 C++: Classes & Objects -2 47 Overloading + and - Operators You have a class FeetInches that allows you to enter a measurement in feet and inches  You want to be able to add and subtract two objects of the class and get a result in feet and inches 6 feet 10 inches + 3 feet 8 inches  9 feet 18inches  10 feet 6 inches 6 feet 4 inches – 3 feet 10 inches  3 feet (-6) inches  2 feet 6 inches  Want operator functions to allow this type of non standard addition and subtraction

48 C++: Classes & Objects -2 48 FeetInches.h #ifndef FEETINCHES_H #define FEETINCHES_H // The FeetInches class holds distances or measurements // expressed in feet and inches. class FeetInches { private: int feet; // To hold a number of feet int inches; // To hold a number of inches void simplify(); // Defined in FeetInches.cpp public: FeetInches(int f = 0, int i = 0) { feet = f; inches = i; simplify(); } void setFeet(int f) { feet = f; } void setInches(int i) { inches = i; simplify(); } int getFeet() const { return feet; } int getInches() const { return inches; } FeetInches operator + (const FeetInches &); // Overloaded + FeetInches operator - (const FeetInches &); // Overloaded - }; #endif

49 C++: Classes & Objects -2 49 FeetInches.cpp // Implementation file for the FeetInches class #include // Needed for abs() #include "FeetInches.h" void FeetInches::simplify() { if (inches >= 12) { feet += (inches / 12); inches = inches % 12; } else if (inches < 0) { feet -= ((abs(inches) / 12) + 1); inches = 12 - (abs(inches) % 12); } //********************************************** // Overloaded binary + operator. * //********************************************** FeetInches FeetInches::operator + (const FeetInches &right) { FeetInches temp; temp.inches = inches + right.inches; temp.feet = feet + right.feet; temp.simplify(); return temp; } //********************************************** // Overloaded binary - operator. * //********************************************** FeetInches FeetInches::operator -(const FeetInches &right) { FeetInches temp; temp.inches = inches - right.inches; temp.feet = feet - right.feet; temp.simplify(); return temp; }

50 C++: Classes & Objects -2 50 FeetInchesMain.cpp int feet, inches; FeetInches first, second, third; // Get a distance from the user. cout << "Enter a distance in feet and inches: "; cin >> feet >> inches; // Store the distance in the first object. first.setFeet(feet); first.setInches(inches); // Get another distance from the user. cout << "Enter another distance in feet and inches: "; cin >> feet >> inches; // Store the distance in second. second.setFeet(feet); second.setInches(inches); // Assign first + second to third. third = first + second; // Display the result. cout << "first + second = "; cout << third.getFeet() << " feet, "; cout << third.getInches() << " inches.\n"; // Assign first - second to third. third = first - second; // Display the result. cout << "first - second = "; cout << third.getFeet() << " feet, "; cout << third.getInches() << " inches.\n"; PROGRAM OUTPUT Enter a distance in feet and inches: 6 10 Enter another distance in feet and inches: 3 8 first + second = 10 feet, 6 inches. first - second = 3 feet, 2 inches.

51 C++: Classes & Objects -2 51 Overloading >,, < and == operators Now I’d like to compare to FeetInches objects to determine if one is less than another, greater than another or if the two are equal First, what rule should we use to compare to FeetInches objects  Assuming that both objects have been “simplified”, compare the feet value of both objects.  If the feet are equal, then compare the inches value

52 C++: Classes & Objects -2 52 Overloading >,, < and == operators Include these statements in FeetInches.h bool operator > (const FeetInches &);// Overloaded > bool operator < (const FeetInches &);// Overloaded < bool operator == (const FeetInches &);// Overloaded == Include these functions in FeetInches.cpp bool FeetInches::operator > (const FeetInches &right) {bool status; if (feet > right.feet) status = true; else if (feet == right.feet && inches > right.inches) status = true; else status = false; return status; } bool FeetInches::operator < (const FeetInches &right) {bool status; if (feet < right.feet) status = true; else if (feet == right.feet && inches < right.inches) status = true; else status = false; return status; } bool FeetInches::operator == (const FeetInches &right) {bool status; if (feet == right.feet && inches == right.inches) status = true; else status = false; return status; }

53 C++: Classes & Objects -2 53 Overloading >,, < and == operators Instantiate two FeetInches objects and compare them int feet, inches; FeetInches first, second; cout << "Enter a distance in feet and inches: "; cin >> feet >> inches; first.setFeet(feet); first.setInches(inches); cout << "Enter another distance in feet and inches: "; cin >> feet >> inches; second.setFeet(feet); second.setInches(inches); // Compare the two objects. if (first == second) cout << "first is equal to second.\n"; if (first > second) cout << "first is greater than second.\n"; if (first < second) cout << "first is less than second.\n"; Enter a distance in feet and inches: 6 10 Enter another distance in feet and inches: 5 3 first is greater than second. Enter a distance in feet and inches: 6 10 Enter another distance in feet and inches: 6 11 first is less than second. Enter a distance in feet and inches: 6 6 Enter another distance in feet and inches: 6 6 first is equal to second.

54 C++: Classes & Objects -2 54 Object Conversion Type of an object can be converted to another type  Automatically done for built-in data types Must write an operator function to perform conversion To convert a FeetInches object to a double : FeetInches::operator double() {double temp=feet; temp+=(inches/12.0); return temp;} To convert a FeetInches object to an int : FeetInches::operator int() {return feet;} //drops the inches  Assuming distance is a FeetInches object, allows statements like: int d = distance;

55 C++: Classes & Objects -2 55 Aggregation Aggregation: a class is a member of a class Supports the modeling of ‘has a’ relationship between classes – enclosing class ‘has a’ enclosed class Same notation as for structures within structures

56 C++: Classes & Objects -2 56 Aggregation class StudentInfo { private: string firstName, LastName; string address, city, state, zip;... }; class Student { private: StudentInfo personalData;... };

57 C++: Classes & Objects -2 57 Aggregation Example char lastName[NAME_SIZE]; char firstName[NAME_SIZE]; char officeNumber[OFFICE_NUM_SIZE]; char title[PUB_SIZE]; char author[PUB_SIZE]; char publisher[PUB_SIZE]; char courseName[COURSE_SIZE]; Instructor instructor; TextBook textbook;


Download ppt "More About Classes. C++: Classes & Objects -2 2 Instance and Static Members Each instance of a class has its own copies of the class’s instance (member)"

Similar presentations


Ads by Google