Automatics, Copy Constructor, Assignment Operator Flashcards
What is an automatic function?
Name four examples covered in this class.
A function which is created by default by the compiler if it isn’t explicitly defined in a class.
Examples:
* Default Constructor
* Destructor
* Copy Constructor
* Assignment Operator (=)
What do the automatic versions of the Default Constructor and Destructor do?
Nothing. They’re just empty functions.
What is a Copy Constructor?
A constructor invoked implicitly whenever something is done that creates a copy of an object.
What actions cause a copy of an object to be created (and thus call the Copy Constructor)?
- An object is defined to have the value of another object of the same type.
Example:
MyObject mo3 = mo2;
// declaration of mo3 being initialized as a copy of mo2
- An object is PASSED BY VALUE to a function.
Doing this causes a copy of an entire object to be created (just like any other variable passed by value) and this is why objects are usually passed by reference or const reference, because it’s more efficient than making a temporary copy due to how large objects can be.
- An object is RETURNED BY VALUE from a function.
Let’s say you have two existing objects of type MyObject (mo1 and mo2).
Will the following line:
mo1 = mo2
…call the copy constructor?
Why or why not?
No.
This line would call the assignment operator, NOT the copy constructor, because both mo1 and mo2 already exist, and no copy is being created to initialize a new object.
How many parameters does a copy constructor have?
One.
It is always an object of the same type as itself.
Example declaration:
className(const className & c);
It’s not required to make the parameter const, but it’s a good idea since a copy shouldn’t modify the original.
What is a Shallow Copy?
This simply means that the object is copied exactly as-is. Each member data value is copied exactly over to the corresponding member data location in the new object. This is sufficient for many cases, but not for ALL cases.
What is a Deep Copy?
This is a copy of an object that also creates new instances of dynamic data within the object such that it points to its own dynamic data rather than the dynamic data of the original object.
When an object contains a pointer that points to dynamic data, which type of copy is required? Why?
Deep Copy
A shallow copy creates problems when the data between two objects is pointing to the same dynamically allocated memory simultaneously because any modifications to that data affects both objects AND it could also create a problem when the original object goes out of scope and deletes the dynamic data, but the new copy is still pointing to that deleted data. That’s a bad time.
What should the Copy Constructor for an object which contains a pointer to dynamically allocated data do?
It should create a new dynamic memory location for the new object to point to which can then have a copy of the original data placed inside of it.
Here’s an example of a deep copy constructor from the Directory file:
Directory::Directory(const Directory & d)
// copies object ‘d’ into the new object being created (this one)
{
// copy the static variables normally
maxsize = d.maxsize;
currentsize = d.currentsize;
// create a new dynamic array for the
// new object’s pointer
entryList = new Entry[d.maxsize];
// copy the dynamic data
for (int i = 0; i < currentsize; i++)
entryList[i] = d.entryList[i];
}
By default, what kind of copy does the assignment operator (=) create?
A shallow copy.
To get a deep copy on a user-defined type with the assignment operator, the operator needs to be overloaded.
When overloading the assignment operator for objects, how should the object be returned?
By Reference.
In order to reference itself, the keyword ‘this’ can be used, which is a pointer to the object’s own address.
To return the reference of THIS, it must be dereferenced like any other pointer:
return *this;
EXAMPLE:
Declaration:
Directory& operator= (const Directory &);
Definition:
Directory& Directory::operator=(const Directory & d);
// copies object ‘d’ into the new object being created (this one)
{
if (this != &d) // only copy if the object passed in is not already this one
{
// since this is not a brand new object, we
// should delete any information currently attached
delete [] entryList; // similar to the copy constructor definition maxsize = d.maxsize; currentsize = d.currentsize; entryList = new Entry[d.maxsize]; for (int i = 0; i < currentsize; i++) entryList[i] = d.entryList[i]; }
return *this; // return the object itself (by reference)
}
What’s wrong with this Copy Constructor declaration?
Movie (const Movie original);
The parameter object is being passed by value, which would require it to be copied, but this is a copy constructor… so it would have to call this same function to do that, which would create a circular dependency. Instead, it needs to be passed by reference. The const is good because we don’t want to change the original object, just copy it. Corrected:
Movie (const Movie& original);
What’s wrong with this assignment operator overload?
Movie operator=(Movie original);
The return type needs to be returned by reference, but in the question it’s returned by value. It should be:
Movie& operator=(Movie original);
The above is technically valid, but could be improved by making the parameter passed by const reference:
Movie& operator=(const Movie& original);
This is more efficient from a memory perspective because a copy of the parameter object is not being made, and it’s safer because the parameter object is constant and thus unmodifiable.
What is an equivalent alternate way to write the following:
Movie movie2 = movie1;
Movie movie2(movie1);
Both call the copy constructor and create a new object, movie2, by copying movie1.