This is the course class in question.
class Course {
//** You may not change the declarations in this private: area.
CourseName name; ///< Name of the course
int numberOfPrerequisites; ///< How many prereqs are currently in the array?
int maxPrerequisites; ///< How many prereqs will fit into the array?
CourseName * prereqs;
Here is what I have as of now. Note that this copy constructor causes some of my unit tests to fail. I cannot change the unit test but instead must fix the copy constructor:
Course::Course(const Course& other)
: name(other.name), numberOfPrerequisites(other.numberOfPrerequisites),
maxPrerequisites(other.maxPrerequisites), prereqs(new CourseName[other.maxPrerequisites])
{
// Copy all prerequisites
for (int i = 0; i < numberOfPrerequisites; ++i)
{
prereqs[i] = other.prereqs[i];
}
}
The unit test that are failing say that once a new course is initialized using another course, when you modify the newly create course it is also changing the original course. Simply put they are the same after modifications when they should be different.
These are the operator overloads that I have tried thus far.
bool Course::operator==(const Course& other) const
{
return name == other.name;
}
Course& Course::operator=(const Course& other)
{
if (this == &other)
return *this;
name = other.name;
numberOfPrerequisites = other.numberOfPrerequisites;
maxPrerequisites = other.maxPrerequisites;
delete[] prereqs;
prereqs = new CourseName[other.maxPrerequisites];
// Copy the prerequisites from the source object to the new object
for (int i = 0; i < numberOfPrerequisites; ++i)
{
prereqs[i] = other.prereqs[i];
}
return *this;
}
This seems to be a homework assignment of some sort, so I do not want to give away too much in this answer.
That said, the comments have identified these things:
operator=.operator==is deficient.The missing dtor will cause memory leaks. Its absence, however, should not cause the copy-ctor or copy-assignment
operator=to fail.If the copy-ctor is doing its job correctly–which seems to be the case–then the only thing that could be going wrong is the copying of
CourseName.At first, I assumed it had a straightforward definition such as this:
But if that were true, then there would be no error in the copy-ctor.
That is when it occurred to me that this is a lesson about deep-copy and deep-compare. Did the instructor implement
CourseNameso that it, too, would require the "Rule of Three?"If so, then the compiler-supplied, default copy-assignment
operator=forCourseNamewould not do the right thing. Neither would an equalityoperator==that did member-wise comparison.Your problem, therefore, may be that you need to work on
CourseNamea bit more.If, not, then we will need to see a Minimal, Reproducible Example in order to analyze further. That should be a complete program, including function
main. An MRE excludes unnecessary detail, but otherwise reproduces the error.What is the "Strong Guarantee?"
The so-called "strong guarantee" is a promise that when an operator such as
operator=oroperator>>fails, the original object is left untouched. It's all-or-nothing: no partial updates are allowed.The
operator=given in the original question does not provide the strong guarantee. It is possible that the call to operatornew[]could fail, throwingstd::bad_alloc. When that happens, you will not be able to recover the original object, because you will have already deleted it.In order to provide the strong guarantee, you need to assign the result of operator
new[]to to a temporary variable, and only update the object after that pointer has been safely received.This is your
operator=, with only the few changes needed to provide the strong guarantee.As identified in the comments, the copy-and-swap idiom is an alternative way to implement
operator=. Copy-and-swap has the benefit of simplicity, and, in addition, provides the strong guarantee.