Chapter 8 Part 2 Destructor Operator Overloading 3


























- Slides: 26
Chapter 8 (Part 2) Destructor & Operator Overloading 3
Sample Code of CRational Addition #include <iostream> using namespace std; // See P. 97 class CRational { public: int numerator; // 分子 int denominator; // 分母 CRational(int p=0, int q=1) : numerator(p), denominator(q) { if (q==0) { cout << "Error! The denominator cannot be 0. n"; exit(1); } } void Print() //印出分子&分母 { cout << numerator; if (denominator != 1) cout << "/" << denominator; } void Add(CRational a, CRational b) //將兩分數相加 { int c; int d; c = a. numerator*b. denominator+a. denominator*b. numerator; d = b. denominator*a. denominator; cout << c; // Simply print out, so you cannot if(d != 1) // add three rational numbers cout << "/" << d ; } }; 4
Another Example class CRational { public: int numerator; // 分子 int denominator; // 分母 CRational(int p=0, int q=1){ numerator=p; denominator=q; } CRational Add(CRational data_a, CRational data_b){ int n =CRational( data_a. numerator*data_b. denominator+ return CRational temp; data_a. numerator*data_b. denominator+ temp. numerator = data_a. numerator*data_b. denominator+ data_b. numerator*data_a. denominator; data_b. numerator*data_a. denominator, data_b. numerator*data_a. denominator; int d = data_a. denominator*data_b. denominator; temp. denominator = data_a. denominator*data_b. denominator; data_a. denominator*data_b. denominator); return temp; CRational(n, d); return } }; 5
Call the member function from main() int main(){ int input_n, input_d; while(1){ printf("please input two Rationaln"); printf("the a's numerator is: "); scanf("%d", &input_n); printf("the a's denominator is: "); scanf("%d", &input_d); CRational a(input_n, (input_d==0? 1: input_d)); printf("the b's numerator is: "); scanf("%d", &input_n); printf("the b's denominator is: "); scanf("%d", &input_d); CRational b(input_n, (input_d==0? 1: input_d)); CRational c; c. Add(a, b); You should handle this in c. Print(); } return 0; } the constructor, not here for every input. 6
How do we calculate d = a + b + c? p For c = a + b: n p For d = a + b + c: n n p temp. Add(a, b); d. Add(temp, c); For e = a + b + c + d: n n n p c. Add(a, b); temp 1. Add(a, b); temp 2. Add(c, d); e. Add(temp 1, temp 2); After we declare a class CRational, it will be more natural if we can simply write c = a + b instead of c. Add(a, b)? Can we do that? 7
Operator Overloading p Operator overloading is a very important capability. n n It allows you to make standard C++ operators, such as +, -, * and so on, work with objects of your own data types. We want to write p n instead of p p if (box 1 > box 2) if (Is. Greater. Than(box 1, box 2)) Let us recall some background of function overloading (Chapter 6). 8
Function Overloading p p p Function overloading allows you to use the same function name for defining several functions as long as they each have different parameter lists. When the function is called, the compiler chooses the correct version according to the list of arguments you supply. The following functions share a common name, but have a different parameter list: n n n int max(int array[], int len); long max(long array[], int len); double max(double array[], int len); 9
Ex 6_07. cpp on P. 311 Three overloaded functions of max() p In main(), C compiler inspect the argument list to choose different version of functions. p 10
Signature p p p The signature of a function is determined by its name and its parameter list. All functions in a program must have unique signatures The following example is not valid overloading n n p double max(long array[], int len); long max(long array[], int len); A different return type does not distinguish a function, if the signatures are the same. 11
Implementing an Overloaded Operator class CBox { public: bool operator> (CBox& a. Box) const; } The word operator here is a keyword. p You declare the operator>() function as const because it doesn’t modify any data members of the class. (P. 393) p 12
Using an Overloaded Operator if (box 1 > box 2) cout << “box 1 is greater than box 2”; p if (box 1. operator>(box 2)) p V 13
Ex 8_03. cpp on P. 449 bool CBox: : operator> (CBox& a. Box) const { return this->Volume() > a. Box. Volume(); } p The left operand is defined implicitly by the pointer this. n p The basic > operator returns a value of type int n n p Q: Can we omit “this->”? 1 for true (P. 56, non-zero value as true) 0 for false. It will be automatically converted to bool. 14
Overloading the Assignment Operator p What’s wrong with the default assignment? n n It simply provides a member-by-member copying process, similar to that of the default copy constructor. They suffer from the same problem (P. 442), when some data members are allocated dynamically. 15
Fixing the Problem CMessage& operator= (const CMessage& a. Mess) { // buffer = string 1; // Release memory for 1 st operand delete [] pmessage; pmessage = new char [ strlen(a. Mess. pmessage) + 1]; // Copy 2 nd operand string to 1 st strcpy(this->pmessage, a. Mess. pmessage); // Return a reference to 1 st operand return *this; } 16
Why Do You Need to Return Something? p Consider this statement n p The assignment operator is rightassociative, so it translates into n n p motto 1 = motto 2 = motto 3; motto 1 = (motto 2. operator=(motto 3)); motto 1. operator=(motto 2. operator=(motto 3)); You must at least return a CMessage object. 17
Why Do You Need to Return a Reference? p Consider another example n p This translates into n p (motto 1 = motto 2) = motto 3; (motto 1. operator=(motto 2)) = motto 3; If the return type is merely CMessage instead of a reference, a temporary copy of the original object is returned. n n Then you are assigning a value to a temporary object! Make sure that your return type is CMessage&. 18
Check Addresses, If Equal The first thing that the operator function does is to delete the memory allocated to the first object (See P. 455 again), and reallocate sufficient memory to accommodate the new string. p What happens to this statement? p n p motto 1 = motto 1 Add this checking: (P. 457) if (this == &a. Mess) return *this; 19
Overloading the Addition Operator p p Suppose we define the sum of two CBox object as a CBox object which is large enough to contain the other two boxes stacked on top of each other. See Figure 8 -4. CBox: : operator+(const CBox& a. Box) const { return CBox( m_Length > a. Box. m_Length ? m_Length : a. Box. m_Length, m_Width > a. Box. m_Width ? m_Width : a. Box. m_Width, m_Height + a. Box. m_Height); } p Ex 8_06. cpp on P. 461 20
Using Classes We want to pack candy into candy boxes, and pack candy boxes to cartons (紙板箱). p The objects candy, candybox, carton, all belong to the CBox class. p We are packing CBox objects into other CBox objects. p 21
Basic Operations of the CBox Class p Calculate the volume of a CBox n p p We have this for the > operator (P. 452) Add two CBox object to produce a CBox object n p operator>() Compare the volume of a CBox object with a specified value n p Volume() Compare the volumes of two CBox objects to determine which is the larger. n p operator+() Multiply a CBox object by an integer to provide a CBox object Determine how many CBox objects of a given size can be packed in another CBox object of a given size. n p This is effectively division, so you could implement this by overloading the / operator. Determine the volume of space remaining in a CBox object after packing it with the maximum number of CBox objects of a given size. n Wasted spaced. 22
The Multiply Operation p If n is even, stack the boxes side-by-side by doubling the m_Width value and only multiplying the m_Height value by half of n. (P. 490) 23
P. 491 // CBox multiply operator this*n CBox operator*(int n) const { if (n % 2) return CBox(m_Length, m_Width, n*m_Height); // n odd else return CBox(m_Length, 2. 0*m_Width, (n/2)*m_Height); // n even } 24
The Division Operation (P. 492) Figure 8 -7 25
Member Function operator/() P. 491 int operator/(const CBox& a. Box) { int tc 1 = 0; int tc 2 = 0; p tc 1 = static_cast<int>((m_Length / a. Box. m_Length)) * static_cast<int>((m_Width / a. Box. m_Width)); tc 2 = static_cast<int>((m_Length / a. Box. m. Width)) * static_cast<int>((m_Width / a. Box. m_Length)); return static_cast<int>((m_Height/a. Box. m_Height)*(tc 1>tc 2 ? tc 1 : tc 2)); } 26
Member Function operator%() p It would be easy to check the remaining space using the functions you have already defined: // Operator to return the free volume in a packed CBox double operator%( const CBox& a. Box, const CBox& b. Box) { return a. Box. Volume() - (a. Box / b. Box) * b. Box. Volume(); } 27
Exercise p Modify CMatrix so that addition is implemented as operator+(). n n You may simply call the member function Add() which you have already defined. Test your implementation with calculations like a+b p a + b + c + d p a + a + a p p Also, try to implement operator-(), and test n a–b–c–d 28