> n; int vector[n]; error C2057: expected constant expression"> > n; int vector[n]; error C2057: expected constant expression">
Download presentation
Presentation is loading. Please wait.
Published byEdgar Harrington Modified over 9 years ago
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(); }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.