> n; int vector[n]; error C2057: expected constant expression"> > n; int vector[n]; error C2057: expected constant expression">

Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 Chapter 8 Destructor & Operator Overloading. 2 Destructor  A destructor is a function that is called when an object is no longer required. A constructor.

Similar presentations


Presentation on theme: "1 Chapter 8 Destructor & Operator Overloading. 2 Destructor  A destructor is a function that is called when an object is no longer required. A constructor."— Presentation transcript:

1 1 Chapter 8 Destructor & Operator Overloading

2 2 Destructor  A destructor is a function that is called when an object is no longer required. A constructor is a function which is called when a new object is created. A constructor is usually used to initiate an object. A destructor is usually used to destroy an object,  This is necessary, when some data members are dynamically allocated. (See Chapter 4)

3 3 Dynamic Memory Allocation (P.194)  Sometimes depending on the input data, you may allocate different amount of space for storing different types of variables at execution time int n = 0; cout << "Input the size of the vector - "; cin >> n; int vector[n]; error C2057: expected constant expression

4 4 Free Store (Heap)  To hold a string entered by the user, there is no way you can know in advance how large this string could be.  Free Store - When your program is executed, there is unused memory in your computer.  You can dynamically allocate space within the free store for a new variable.

5 5 The new Operator  Request memory for a double variable, and return the address of the space double* pvalue = NULL; pvalue = new double;  Initialize a variable created by new pvalue = new double(9999.0);  Use this pointer to reference the variable (indirection operator) *pvalue = 1234.0;

6 6 The delete Operator  When you no longer need the (dynamically allocated) variable, you can free up the memory space. delete pvalue;  Release memory pointed to by pvalue pvalue = 0;  Reset the pointer to 0  After you release the space, the memory can be used to store a different variable later.

7 7 Allocating Memory Dynamically for Arrays  Allocate a string of twenty characters char* pstr; pstr = new char[20]; delete [] pstr;  Note the use of square brackets to indicate that you are deleting an array. pstr = 0;  Set pointer to null

8 8 Dynamic Allocation of Multidimensional Arrays  Allocate memory for a 3x4 array double (*pbeans)[4]; pbeans = new double [3][4];  Allocate memory for a 5x10x10 array double (*pBigArray)[10][10]; pBigArray = new double [5][10][10];  You always use only one pair of square brackets following the delete operator, regardless of the dimensionality of the array. delete [] pBigArray ;

9 9 The Default Destructor  The destructor for a class is a member function with the same name as the class, preceded by a tilde (~). For the CBox class, the prototype of the clas destructor is ~CBox(); A destructor has no parameters.  Ex8_01.cpp on P.410 ~CBox() { cout << “Destructor called.” << endl; }

10 10 Class CMessage (1)  Suppose you want to define a class Each object contains a text string. You don ’ t want to declare a data member as a large character array (like char [200] ), So you ’ ll allocate memory in the free store for the message when an object is created.  This is your constructor: CMessage(const char* text = “Default message”) { pmessage = new char[strlen(text) + 1]; strcpy(pmessage, text); }

11 11 strlen, strcmp, strcpy #include using std::cout; using std::endl; int main() { char a[20] = "NCNU"; char b[20] = "Sunday"; cout << sizeof a << " " << strlen(a) << endl; // size = 20, string length = 4 if (strcmp(a,b) < 0) cout << "The string " << a << " is less than " << b << endl; strcpy(a, b); cout << a << endl; }

12 12 Destructors and Dynamic Memory Allocation CMessage(const char* text = “Default message”) { pmessage = new char[strlen(text) + 1]; strcpy(pmessage, text); } ~CMessage() { cout << “Destructor called.” << endl; delete [] pmessage; }

13 13 Ex8_02.cpp on P.413  As the output indicates, the destructor is called only once. The object motto is created automatically, so the compiler also calls the destructor automatically. If you manually “ delete pM ”, it will free the memory pointed to by pM. Because the pointer pM points to a CMessage object, this causes the destructor to be invoked.

14 14 Behavior of a Default Copy Constructor CMessage motto1(“Radiation fades your genes.”); CMessage motto2(motto1); // Calls default copy constructor

15 15 Q: What will the second motto2.ShowIt() display? CMessage motto1(“A stitch in time saves nine.”); CMessage motto2(motto1); motto2.ShowIt(); // Display 2nd message strcpy(motto1.pmessage, "Time and tide wait for no man."); motto1.ShowIt(); // Display 1st message motto2.ShowIt(); // Display 2nd message

16 16 Implementing a Copy Constructor  We don ’ t want the two objects sharing the same string in the memory.  If motto1 is destroyed, the pointer in motto2 will become invalid.  Let us implement a copy constructor to generate an object which is identical but independent of the old one. CMessage(const CMessage& initM) { pmessage = new char [ strlen(initM.pmessage) +1 ]; strcpy(pmessage, initM.pmessage); } Exercise: Modify Ex8_02.cpp to implement this copy constructor.

17 17 Operator Overloading  Operator overloading is a very important capability. 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  if (box1 > box2) instead of  if (IsGreaterThan(box1, box2))  Let us recall some background of function overloading (Chapter 6).

18 18 Function Overloading  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: int max(int array[], int len); long max(long array[], int len); double max(double array[], int len);

19 19 Ex6_07.cpp on P.293  Three overloaded functions of max()  In main(), C compiler inspect the argument list to choose different version of functions.

20 20 Signature  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 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.

21 21 Implementing an Overloaded Operator class CBox { public: bool operator> (CBox& aBox) const; }  The word operator here is a keyword.  You declare the operator>() function as const because it doesn ’ t modify any data members of the class. (P.369)

22 22 Using an Overloaded Operator  if (box1 > box2) cout << “ box1 is greater than box2 ” ;  if (box1.operator>(box2)) V

23 23 Ex8_03.cpp on P.422 bool CBox::operator> (CBox& aBox) const { return this->Volume() > aBox.Volume(); }  The left operand is defined implicitly by the pointer this.  The basic > operator returns a value of type int 1 for true 0 for false.  It will be automatically converted to bool.

24 24 Overloading the Assignment Operator  What ’ s wrong with the default assignment? It simply provides a member-by-member copying process, similar to that of the default copy constructor. They suffer from the same problem, when some data members are allocated dynamically.

25 25 Fixing the Problem CMessage& operator= (const CMessage& aMess) { // Release memory for 1 st operand delete [] pmessage; pmessage = new char [ strlen(aMess.pmessage) + 1]; // Copy 2 nd operand string to 1 st strcpy(this->pmessage, aMess.pmessage); // Return a reference to 1 st operand return *this; }

26 26 Why Do You Need to Return Something?  Consider this statement motto1 = motto2 = motto3;  The assignment operator is right- associative, so it translates into motto1 = (motto2.operator=(motto3)); motto1.operator=(motto2.operator=(motto3));  You must at least return a CMessage object.

27 27 Why Do You Need to Return a Reference?  Consider another example (motto1 = motto2) = motto3;  This translates into (motto1.operator=(motto2)) = motto3;  If the return type is merely CMessage instead of a reference, a temporary copy of the original object is returned. Then you are assigning a value to a temporary object! Make sure that your return type is CMessage&.

28 28 Check Addresses, If Equal  The first thing that the operator function does is to delete the memory allocated to the first object, and reallocate sufficient memory to accommodate the new string.  What happens to this statement? motto1 = motto1  Add this checking: if (this == &aMess) return *this;

29 29 Overloading the Addition Operator  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 CBox::operator+(const CBox& aBox) const { return CBox( m_Length > aBox.m_Length ? m_Length : aBox.m_Length, m_Width > aBox.m_Width ? m_Width : aBox.m_Width, M_Height + aBox.m_Height); }  Ex8_06.cpp on P.434

30 30 Using Classes  We want to pack candy into candy boxes, and pack candy boxes to cartons.  The objects candy, candybox, carton, all belong to the CBox class.  We are packing CBox objects into other CBox objects.

31 31 Basic Operations of the CBox Class  Calculate the volume of a CBox Volume()  Compare the volumes of two CBox objects to determine which is the larger. operator>()  Compare the volume of a CBox object with a specified value We have this for the > operator (P.414)  Add two CBox object to produce a CBox object 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. 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. Wasted spaced.

32 32 The Multiply Operation  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.

33 33 // 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 }

34 34 The Division Operation  Correct some mistakes in Figure 8-7. L=3 L=8

35 35 Member Function operator/()  P.451 int operator/(const CBox& aBox) { int tc1 = 0; int tc2 = 0; tc1 = static_cast ((m_Length / aBox.m_Length)) * static_cast ((m_Width / aBox.m_Width)); tc2 = static_cast ((m_Length / aBox.mWidth)) * static_cast ((m_Width / aBox.m_Length)); return static_cast ((m_Height/aBox.m_Height)*(tc1>tc2 ? tc1 : tc2)); }

36 36 Member Function operator%()  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& aBox, const CBox& bBox) { return aBox.Volume() - (aBox / bBox) * bBox.Volume(); }


Download ppt "1 Chapter 8 Destructor & Operator Overloading. 2 Destructor  A destructor is a function that is called when an object is no longer required. A constructor."

Similar presentations


Ads by Google