# Lecture 4 --- Classes II: Copy Constructor, Assignment Operator, Destructor, and Non-member Operators ## 4.1 Member Initializer List in C++ A **member initializer list** is a special syntax in C++ that allows class members to be initialized directly before the constructor body executes. It is used in the constructor definition, right after the parameter list and before the body of the constructor. ### Syntax ```cpp ClassName(parameter_list) : member1(value1), member2(value2), ... { // Constructor body (optional, can be empty) } ``` ### Example ```cpp #include #include class MyClass { private: std::string name; public: // Constructor with member initializer list MyClass(const std::string& initName) : name(initName) {} void display() const { std::cout << "Name: " << name << std::endl; } }; int main() { MyClass obj("Alice"); obj.display(); // Output: Name: Alice return 0; } ``` ## 4.2 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.3 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 class MyClass { private: std::string name; public: MyClass(const std::string& initName) : name(initName) {} MyClass& operator=(const MyClass& other) { name = other.name; // Copy data return *this; } void print() const { std::cout << "Name: " << name << std::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.4 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 class MyClass { public: MyClass() { std::cout << "Constructor called" << std::endl; } ~MyClass() { std::cout << "Destructor called" << std::endl; } }; int main() { MyClass obj1; // Constructor called MyClass obj2; // Constructor called // Destructor will be called automatically at the end of scope return 0; } ``` **Question**: in the above example, obj1's destructor or obj2's destructor, which one gets called first? ## 4.5 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.6 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)