When you define a class in C++, the compiler automatically provides four special member functions: - Default constructor (no parameters, empty body)
- Default destructor (no parameters, empty body)
- Default copy constructor (performs value copy of member variables)
- Assignment operator
operator=(performs value copy of member variables)
Problem Description
When a class contains members that point to heap-allocated memory, performing assignment operations can introduce deep and shallow copy porblems. Consider this example: ``` class Person { public: Person(int age) { // Allocate age data on the heap m_Age = new int(age); }
// Pointer to age
int *m_Age;
};
### Solution
The assignment operator can be overloaded to properly handle deep copying: ```
class Employee
{
public:
Employee(int salary)
{
// Allocate salary data on the heap
m_Salary = new int(salary);
}
// Overload assignment operator
Employee& operator=(Employee& emp)
// Cannot return void; enables chained assignment like a=b=c
{
// Check if current object already has heap memory, release it first before deep copy
if (m_Salary != NULL)
{
delete m_Salary;
m_Salary = NULL;
}
// Compiler-provided code performs shallow copy
// m_Salary = emp.m_Salary;
// Implement deep copy to resolve shallow copy issue
m_Salary = new int(*emp.m_Salary);
// Return reference to this object
return *this;
}
~Employee()
{
if (m_Salary != NULL)
{
delete m_Salary;
m_Salary = NULL;
}
}
// Salary pointer
int *m_Salary;
};
void testAssignment()
{
Employee emp1(5000);
Employee emp2(7000);
Employee emp3(9000);
emp3 = emp2 = emp1; // Chained assignment operation
cout << "Employee 1 salary: " << *emp1.m_Salary << endl;
cout << "Employee 2 salary: " << *emp2.m_Salary << endl;
cout << "Employee 3 salary: " << *emp3.m_Salary << endl;
}
int main() {
testAssignment();
return 0;
}
Summary
Both copy constructors and assignment operator overloading can resolve deep and shallow copy problems. The distinction lies in when they are invoked: the copy constructor is called during object initialization (e.g., Person p2 = p1;), while the assignment operator is called when assigning to an already-constructed object (e.g., p2 = p1;).