Overloading the = Operators in C++

You need to overload the = operator to perform a customized copy operation for an object.

By default, the = operator performs a memberwise copy from one object to the other. For example, the following code copies r2 to r1.

1 Rational r1(1, 2);
2 Rational r2(
4, 5);
3 r1 = r2;
4 cout <<
“r1 is ” << r1 << endl;
5 cout <<
“r2 is ” << r2 << endl;

So, the output is

The behavior of the = operator is the same as that of the default copy constructor. It per­forms a shallow copy, meaning that if the data field is a pointer to some object, the address of the pointer is copied rather than its contents. In Section 11.15, “Customizing Copy Construc­tors,” you learned how to customize the copy constructor to perform a deep copy. However, customizing the copy constructor does not change the default behavior of the assignment copy operator =. For example, the Course class defined in Listing 11.19, CourseWithCustomCopy- Constructor.h, has a pointer data field named students which points to an array of string objects. If you run the following code using the assignment operator to assign course1 to course2, as shown in line 9 in Listing 14.10, you will see that both course1 and course2 have the same students array.

Listing 14.10 DefaultAssignmentDemo.cpp

1 #include <iostream>
2
#include “CourseWithCustomCopyConstructor.h” // See Listing 11.19
3 using namespace std;
4
5
int main()
6 {
7    Course course1(
“Java Programming”, 10);
8    Course course2(
“C++ Programming”, 14);
9    course2 = course1;
10
11   course1.addStudent(
“Peter Pan”); // Add a student to course1
12   course2.addStudent(“Lisa Ma”); // Add a student to course2

13
14    cout <<
“students in course1: ” <<
15    course1.getStudents()[
0] << endl;
16    cout <<
“students in course2: ” <<
17    course2.getStudents()[
0] << endl;
18
19   
return 0;
20 }

To change the way the default assignment operator = works, you need to overload the = opera­tor, as shown in line 17 in Listing 14.11.

Listing I4.II CourseWithEqualsOperatorOverloaded.h

1 #ifndef COURSE_H
2
#define COURSE_H
3
#include <string>
4
using namespace std;
5
6
class Course
7 {
8
public:
9     Course(
const string& courseName, int capacity);
10    ~Course();
// Destructor
11    Course(const Course&); // Copy constructor
12    string getCourseName() const;
13   
void addStudent(const string& name);
14   
void dropStudent(const string& name);
15    string* getStudents()
const;
16   
int getNumberOfStudents() const;
17   
const Course& operator=(const Course& course);
18
19
private:
20    string courseName;
21    string* students;
22   
int numberOfStudents;
23   
int capacity;
24 };
25
26
#endif

In Listing 14.11, we define

const Course& operator=(const Course& course);

Why is the return type Course not void? C++ allows expressions with multiple assignments, such as:

course1 = course2 = course3;

In this statement, course3 is copied to course2, and then returns course2, and then course2 is copied to coursel. So the = operator must have a valid return value type.

The implementation of the header file is given in Listing 14.12.

Listing 14.12 CourseWithEqualsOperatorOverloaded.cpp

1 #include <iostream>
2
#include “CourseWithEqualsOperatorOverloaded.h”
3 using namespace std;
4
5 Course::Course(
const string& courseName, int capacity)
6 {
7    numberOfStudents =
0;
8   
this->courseName = courseName;
9   
this->capacity = capacity;
10   students =
new string[capacity];
11 }
12
13 Course::~Course()
14 {
15   
delete [] students;
16 }
17
18 string Course::getCourseName()
const
19 {
20   
return courseName;
21 }
22
23
void Course::addStudent(const string& name)
24 {
25   
if (numberOfStudents >= capacity)
26    {
27        cout <<
“The maximum size of array exceeded” << endl;
28        cout <<
“Program terminates now” << endl;
29        exit(
0);
30    }
31
32    students[numberOfStudents] = name;
33    numberOfStudents++;
34 }
35
36
void Course::dropStudent(const string& name)
37 {
38   
// Left as an exercise
39 }
40
41 string* Course::getStudents()
const
42 {
43   
return students;
44 }
45
46
int Course::getNumberOfStudents() const
47 {
48   
return numberOfStudents;
49 }
50
51 Course::Course(
const Course& course) // Copy constructor
52 {
53    courseName = course.courseName;
54    numberOfStudents = course.numberOfStudents;
55    capacity = course.capacity;
56    students =
new string[capacity];
57 }
58

59 const Course& Course::operator=(const Course& course)
60 {
61    courseName = course.courseName;
62    numberOfStudents = course.numberOfStudents;
63    capacity = course.capacity;
64    students =
new string[capacity];
65
66   
return *this;
67 }

Line 66 returns the calling object using *this. Note that this is the pointer to the calling object, so *this refers to the calling object

Listing 14.13 gives you a new test program that uses the overloaded = operator to copy a Course object. As shown in the sample output, the two courses have different students array.

Listing 14.13 CustomAssignmentDemo.cpp

1 #include <iostream>
2
#include “CourseWithEqualsOperatorOverloaded.h”
3 using namespace std;
4
5
int main()
6 {
7     Course course1(
“Java Programming”, 10);
8     Course course2(
“C++ Programming”, 14);
9     course2 = course1;
10
11    course1.addStudent(
“Peter Pan”); // Add a student to course1
12    course2.addStudent(“Lisa Ma”); // Add a student to course2
13
14    cout <<
“students in course1: ” <<
15    course1.getStudents()[
0] << endl;
16    cout <<
“students in course2: ” <<
17    course2.getStudents()[
0] << endl;
18
19   
return 0;
20 }

Source: Liang Y. Daniel (2013), Introduction to programming with C++, Pearson; 3rd edition.

Leave a Reply

Your email address will not be published. Required fields are marked *