CMSC202 Lecture Notes for week 5

During the week of March 1, we discussed the following:

Deep and Shallow copy, overloaded assignment, and copy constructors

The problem: Shallow copy
Examine the first version of the "thing" class - header and implementation. It has no copy constructor or overloaded assignment. When we use this class in a program, we discover that the assignment operation causes the copy (the variable W in this case) to share memory with the original class instance (Z). (See Output from CC compiler). This is something we certainly do not wish to happen. When we make a copy of a class instance, we expect that changes to the copy would leave the original unchanged!

Why does this happen? The default assignment operator produces a shallow i.e. bit-by-bit) copy of the argument (on the right hand side of the = operator), but not of the dynamically allocated memory. To make sure that we get a complete copy of a class instance, we overload the = operator.>p> Our second stab at the thing class, Header and implementaiton show the signature for this overloaded member function is

	thing & operator = (const thing &);
The code is not particularly difficult. It just creates a separate copy of the dynamic array (_bucket), so that the host member (the instance on the left side of the operator) is a complete replica of the argument (the thing on the right side of the operator). The only tricky thing we do is make sure that we check for a statement of the form X = X.

The same problem occurs when a function receives a value parameter (call by value). C++ will, unless we do something about it, make a bit-by-bit copy of the actual parameter. This is fine for numeric or pointer arguments, but for class instances, a shallow copy of the parameter will leave the function able to manipulate the deep structures of the actual parameter. This can be quite problematic, but there is a (relatively) easy solution to the problem: the copy constructor. It is an overloaded constructor with form

	thing (const thing &)
Note that the constructor (as with the overloaded = operator) takes a const reference to a class instance, and like the overloaded assignment, it makes a copy of dynamic memory.

An intereting observation

When we ran the version of thing2 that was built with the CC compiler, we found that the object created when foo1 was called was in fact made with the copy constructor, BUT when foo terminated, surprisingly enough, the destructor was not invoked until the program terminated. The object that was created by the copy constructor became unaccessible, but it was there. When we compiled and executed the same program with the g++ compiler, the results show that the destructor was invoked when the function terminated. Does this mean that we should use the g++ compiler? Not necessarily. We'll see some more examples of this next week.

overloading the [] operator

We noted that the thing class is, in essence, an array. We might wish to make this a "safe array", i.e. one that doesn't allow use of array subscripts outside the range of the array itself. To do this, we can overload the [] operator. The form of this member function is again standard:
	int& operator [] (const thing &);
(I suppose I put this here to show a number of functions that use a const thing reference as an argument!) The code is
// safe array subscripting 
// overloaded operator []
int& thing::operator[] (int x) {
        if (x < 0 || x >_count) {
                cerr << "out of range index\n";
                exit(1);
        }
        return (_bucket[x]);
}
We note that the [] operator (isn't that an odd way to think of array indexing? as an operator? Well, why not??) checks its argument, an array index. If the index is out of range, then we just terminate gracefully. This prevents us from having an array index run amok, which is a very difficult debugging problem.
We could have used assertions in the calling program to accomplish the same result, but that violates our notion about OOP that the object itself should know what to do with its arguments.

Previous Lecture
Next Lecture


Last Modified: 6 Mar 1999 12:34:08 EST by Mitch Edelman edelman@cs.umbc.edu

Back up to Spring 1999 CMSC 202 Section Homepage