What is the name of a member function of a class that has the same name as the class that has no return type?
To use the string class you must #include
To use the vector class you must #include
TEST YOURSELF NOW
Every class that has a pointer data member should include the following member functions:
An object's destructor function is called when that object is about to "go away"; i.e., when:
For example, consider the following function, with line numbers included for reference:
The scope of variable L1 is the body of the while loop (lines 4 to 6). L1's constructor function is called at the beginning of every iteration of the loop, and its destructor function is called at the end of every iteration of the loop. Note that if the loop included a break or continue statement, the destructor would still be called. Variable p is a pointer to an IntList. When an IntList object is allocated using new at line 2, that object's constructor function is called. When the storage is freed at line 7, the object's destructor function is called (and then the memory for the Intlist itself is freed). TEST YOURSELF NOW Why isn't the destructor function of a reference parameter called at the end of the function? Destructor functions are defined using syntax similar to that used for the constructor function (the name of the class followed by a double colon followed by the name of the function). For example, the definition of the Intlist destructor function would look like this:
NOTE: If you don't write a destructor function for a class that includes pointers to dynamically allocated storage, your code will still work, but you will probably have some storage leaks. To understand more about storage management and destructor functions, let's consider a simpler version of the example code give above:
An object's copy constructor is called (automatically, not by the programmer) when it is created, and needs to be initialized to be a copy of an existing object. This happens when an object is:
Example
On line 6, variable L1 is passed as a value parameter to function f. The corresponding formal parameter is L. When the call is executed, L's copy constructor is called to initialize L to be a copy of the actual parameter, L1. On line 10, variable tmp1 is declared to be an IntList, initialized to be the same as variable L. When line 10 is executed, tmp1's copy constructor is called to initialize tmp1 to be a copy of L. Similarly, when line 11 is executed, tmp2's copy constructor is called to initialize tmp2 to be a copy of L. On line 13, variable tmp1 is returned as the result of calling function f. When line 13 is executed, a copy constructor is called to make a copy of tmp1 to be returned. (Later, that copy is used as the right-hand side of the assignment on line 6.) If you don't write a copy constructor, the compiler will provide one that just copies the value of each data member. If some data member is a pointer, this causes aliasing (both the original pointer and the copy point to the same location), and may lead to trouble. For example, consider the following code:
TEST YOURSELF NOW Consider the StrList class defined below. A StrList stores a list of strings in a linked list pointed to by the StrList's head field. The Lookup operation determines whether a given string is in the list; if it is there, it is moved to the front of the list, and the value true is returned (otherwise, the list is unchanged, and the value false is returned).
Recall that the declaration of a class's copy constructor is similar to that of its default (no-argument) constructor: the function has no return type (not even void), and its name is the same as the name of the class. However, unlike the default constructor, the copy constructor has one argument: its type is the class, and it is a const reference parameter. The argument is the object that the copy constructor is supposed to copy. For example:
The definition of the copy constructor (the actual code for the function) should be put in a ".C" file, along with the code for the other class member functions. The copy constructor should copy the values of all non-pointer data members, and should copy the objects pointed to by all pointer data members. For example, the copy constructor for the IntList class should perform the following tasks:
In C++ you can assign from one class object to another (of the same type). For example:
If a class includes pointer fields, the default class assignment causes aliasing, and as we have seen in the case of the copy constructor, this can lead to trouble! For example, if the L2.Items array is full when the assignment is done, then a subsequent call to L1.AddToFront will cause the array to be returned to free storage (so L2.Items will become a dangling pointer). The default assignment can also cause storage leaks when the class has a pointer field. For example, when L1 = L2; is executed, L1.Items is simply overwritten with the value in L2.Items, the array that L1 was pointing to is not returned to free storage (and that storage is now lost). To prevent these problems, you should always define operator= as a class member function for a class with a pointer field. The declaration of the member function looks like this for the IntList class:
Note that IntList's operator= function returns an IntList. This is to permit chained assignment, for example: L1 = L2 = L3;. When this statement is executed, the expression L2 = L3 is evaluated first; the result of evaluating that expression is used as the right-hand side of the assignment to L1. The operator= function returns its result by reference (that's what the ampersand means). This is done for efficiency, to prevent the IntList copy constructor being called to make a copy of the returned value. Note that operator= differs from the copy constructor in three important ways: Here is the definition of operator= for the IntList class:
To check whether the assignment was L1 = L1, we compare the pointer this with the address of the parameter, L; in the case of L1 = L1, the parameter is L1, so its address is the same as the address that is the value of this. Be sure to include this test every time you write an operator= function! We also make use of this for the returned value; the type to be returned is IntList (not pointer to IntList) so we return *this (the IntList pointed to by this) rather than plain this. Every class that has a pointer data member should include the following member functions: If you don't write a copy constructor, or you don't write operator=, your code may not work correctly; there may be attempts to dereference dangling pointers (which may cause runtime errors, or may cause garbage values to be assigned to some variables), and/or some data may be lost or corrupted. A kind of compromise is to forbid the use of the copy constructor and the assignment of two class objects. You can do this by declaring the copy constructor and operator= as private member functions (just declaring them is enough; you do not need to write the actual code). In this case, any code that would normally cause the copy constructor or operator= to be called will instead cause a compile-time error. |