# Lecture 4 --- Classes II: Copy Constructor, Assignment Operator, Destructor, and Non-member Operators ## 4.1 Copy Constructor - A copy constructor is a constructor which is used to create a new object as a copy of an existing object of the same class. - Copy constructors get called when you create a new object by copying an existing object using the assignment operator (=), or when you pass an object by value to a function. ### Copy Constructor Syntax ```cpp ClassName(const ClassName& other); ``` ### Copy Constructor Example ```cpp #include class MyClass { private: int value; public: // Constructor MyClass(int val) : value(val) {} // Copy Constructor MyClass(const MyClass& other) { value = other.value; std::cout << "Copy Constructor Called!" << std::endl; } void display() const { std::cout << "Value: " << value << std::endl; } }; int main() { MyClass obj1(10); MyClass obj2 = obj1; // Copy constructor is called here obj2.display(); // Output: Value: 10 return 0; } ``` ## 4.2 Assignment Operator - The assignment operator (=) is used to copy the values from one object to another after both objects have been created. ### Assignment Operator Syntax: ```cpp ClassName& operator=(const ClassName& other); ``` ### Assignment Operator Example: ```cpp #include #include using namespace std; class MyClass { private: string name; // Using a standard string (no pointers) public: MyClass(const string& initName) : name(initName) {} MyClass& operator=(const MyClass& other) { name = other.name; // Copy data return *this; } void print() const { cout << "Name: " << name << endl; } }; int main() { MyClass obj1("Object1"); MyClass obj2("Object2"); obj1 = obj2; // Assignment operator invoked obj1.print(); // Output: Name: Object2 return 0; } ``` All C++ class objects have a special pointer defined called **this** which simply points to the current class object, and the expression **this* is a reference to the class object. Assignment operators of the form: ```cpp obj1 = obj2; ``` are translated by the compiler as: ```cpp obj1.operator=(obj2); ``` - Cascaded assignment operators of the form: ```cpp obj1 = obj2 = obj3; ``` are translated by the compiler as: ```cpp obj1.operator=(obj2.operator=(obj3)); ``` - Therefore, the value of the assignment operator (obj2 = obj3) must be suitable for input to a second assignment operator. This in turn means the result of an assignment operator ought to be a reference to an object. **Note**: In C++, the assignment operator is used for assignment after an object has already been created. And because of that, the following two code snippets behave differently. ```cpp myClass A = B; ``` This one line will invoke the copy constructor, rather than the assignment operator. And this behavior is called copy initialization. ```cpp myClass A; A = B; ``` These two lines will: the first line creates the object A, and the second line invokes the assignment operator. ## 4.3 Destructor (the “constructor with a tilde/twiddle”) A **destructor** is a special member function automatically called when an object goes out of scope or is explicitly deleted. ### Destructor Syntax ```cpp ~ClassName(); ``` ### Destructor Example ```cpp #include using namespace std; class MyClass { public: MyClass() { cout << "Constructor called\n"; } ~MyClass() { cout << "Destructor called\n"; } }; int main() { MyClass obj; // Constructor called // Destructor will be called automatically at the end of scope return 0; } ``` ## 4.4 Overloading `operator<<` in C++ ### Purpose The `operator<<` is commonly overloaded to enable custom objects to be output using streams such as `std::cout`. ### Example ```cpp #include #include class Person { private: std::string name; int age; public: // Constructor Person(const std::string& name, int age) : name(name), age(age) {} // Public getters std::string getName() const { return name; } int getAge() const { return age; } }; // Non-member function std::ostream& operator<<(std::ostream& os, const Person& person) { os << "Name: " << person.getName() << ", Age: " << person.getAge(); return os; } int main() { Person p("Alice", 30); std::cout << p << std::endl; // Output: Name: Alice, Age: 30 return 0; } ``` **Question:** Can we overload this operator as a member function? ## 4.5 Exercises - [Leetcode problem 56: Merge Intervals](https://leetcode.com/problems/merge-intervals/). Solution: [p56_mergeintervals.cpp](../../leetcode/p56_mergeintervals.cpp) - [Leetcode problem 905: Sort Array By Parity](https://leetcode.com/problems/sort-array-by-parity/). Solution: [p905_sortarraybyparity.cpp](../../leetcode/p905_sortarraybyparity.cpp) - [Leetcode problem 1929: Concatenation of Array ](https://leetcode.com/problems/concatenation-of-array/). Solution: [p1929_concatenationofarray.cpp](../../leetcode/p1929_concatenationofarray.cpp)