Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Panel
panelIconId1f4a1
panelIcon:bulb:
panelIconText💡
bgColor#F4F5F7

Imagine you have a "House" object. This house object contains a number of "Room" objects. Now, if you want to create an exact copy of this house, you'd also want to create copies of each of these rooms.

If you do a shallow copy (the default copy behavior in C++), you end up with a new house, but the rooms in this new house are exactly the same rooms as the original house. If you make a change in any of the rooms, it will reflect in both the houses because they both refer to the same set of rooms.

Now, think of a deep copy. When you make a deep copy of the house, not only do you create a new house, but you also create new, separate rooms for this house. Now, if you change anything in the rooms of the new house, it will not affect the rooms in the original house. They are independent of each other.

In terms of programming and specifically in C++, when you're making a deep copy, you need to define a custom copy constructor. In this copy constructor, you would allocate new memory for the pointer in the new object (the new house in our analogy) and then copy the actual values (rooms) from the source object to the newly allocated memory.

By doing so, any changes you make to the objects (rooms) in the copied object (new house) do not affect the objects (rooms) in the original object (old house), preventing any unintentional changes or deletions. This is why it's known as a deep copy - you're copying everything, not just the top-level structure.

Here is an example of a deep copy:

  1. Person.h - This is the header file where the class declaration will be placed.

Code Block
languagecpp
// Person.h
#ifndef PERSON_H
#define PERSON_H

#include <iostream>
#include <string>
using namespace std; 

class Person {
public:
    // 2 argument constructor
    Person(const std::string& name, int age);
    // Copy constructor
    Person(const Person& other);
    // Assignment operator
    Person& operator=(const Person& other);
    // Destructor
    ~Person();
    // Functions
    void introduce();
    void setID(int newID); // Setter for id

private:
    string name;
    int age;
    int* id; // Pointer to dynamically allocated memory
};

#endif // PERSON_H
  1. Person.cpp - This is the source file where the class definitions (implementation) will be placed.

Code Block
languagecpp
// Person.cpp
#include "Person.h"

Person::Person(const std::string& name, int age) : name(name), age(age) {
    id = new int(12345); // Allocate memory for id
}

Person::Person(const Person& other) : name(other.name), age(other.age) {
    id = new int(*other.id); // Allocate memory and copy id
}

Person& Person::operator=(const Person& other) {
    if (this != &other) { // Avoid self-assignment
        name = other.name;
        age = other.age;

        delete id; // Deallocate existing id memory
        id = new int(*other.id); // Allocate new memory and copy id
    }
    return *this;
}

Person::~Person() {
    delete id; // Deallocate memory for id
}

void Person::introduce() {
    cout << "Hi, my name is " << name << " and I am " << age 
              << " years old. My ID is " << *id << "." << endl;
}

void Person::setID(int newID) {
    *id = newID; // Set the value of id
}
  1. main.cpp - The file to use the Person class.

Code Block
languagecpp
// main.cpp
#include "Person.h"

int main() {
    Person personOne("Kevin", 39);
    Person personTwo = personOne; // Use copy constructor
    
    personOne.introduce();
    personTwo.introduce();
    
    cout << endl << "Now lets change the ID of personOne " << endl;
    
    personOne.setID(54321); // Change ID of personOne
    
    personOne.introduce();
    personTwo.introduce(); // personTwo will have the original ID
    
    // Demonstrating assignment operator
    Person personThree("Alice", 25);
    personThree = personOne; // Use assignment operator
    personThree.introduce(); // personThree will have the same ID as personOne
    
    return 0;
}

Image Removed

In the main() function:

  • Person personOne("Kevin", 39) creates a Person object named personOne.

  • Person personTwo = personOne uses the copy constructor to create a new Person object personTwo that's a copy of personOne.

  • Then, it prints the information of personOne and personTwo, showing that both have the same name, age, and id.

  • It changes the id of personOne and prints the information again. You'll see that personOne's id has changed, but personTwo's id remains the same, demonstrating that the copy constructor made a separate copy of the id. This concept is often referred to as deep copying in C++.