Search code examples
c++classc++17dynamic-memory-allocationcopy-constructor

Creating a C++ object with and without new keyword


Creating an object with new keyword:

#include <iostream>
#include <string>

using namespace std;

class Person {
  private:
  string name;

  public:
  Person(string name) {
    setName(name);
  }

  string getName() {
    return this->name;
  }

  void setName(string name) {
    this->name = name;
  }
};

int main() {
  Person *person1 = new Person("Rajat");
  Person *person2 = person1;

  person2->setName("Karan");

  cout << person1->getName() << endl;
  cout << person2->getName() << endl;

  return 0;
}

Output:

Karan  
Karan

Creating an object without new keyword:

#include <iostream>
#include <string>

using namespace std;

class Person {
  private:
  string name;

  public:
  Person(string name) {
    setName(name);
  }

  string getName() {
    return this->name;
  }

  void setName(string name) {
    this->name = name;
  }
};

int main() {
  Person person1("Rajat");
  Person person2 = person1;

  person2.setName("Karan");

  cout << person1.getName() << endl;
  cout << person2.getName() << endl;

  return 0;
}

Output:

Rajat  
Karan  

I expected the output to be 'Karan Karan' as I thought in Person person2 = person1, person2 refers to the same person1. But it isn't the case.

Can someone please explain what does the line Person person2 = person1 do under the hood? Does it create a totally new object?


Solution

  • Let's see what's going on in the background.

    First case

    • While using new keyword, new created an object and returned a pointer to that object.

                                 +--------------------------+
             person1 ----------> |    Person Object         |
                                 |        name = Rajat      |
                                 +--------------------------+
      
    • You then copied the address to the object in another pointer to object. So basically now both pointers point to the same object.

                                 +--------------------------+
             person1 ----------> |    Person Object         |
                                 |        name = Rajat      |
             person2-----------> |                          |
                                 +--------------------------+
      
    • Now, You then changed the value of name using one pointer and changing the value using one pointer changed both person1 and person2.

    person2->setName("Karan")
    
                                   +--------------------------+
               person1 ----------> |    Person Object         |
                                   |        name = Karan      |
               person2-----------> |                          |
                                   +--------------------------+
    

    Is it so??

    No! Basically it changed for only the object it points. Hence for one object. In fact, there were never two objects, two objects never got created. It was the same object pointed by two pointers.

    In second case

    • You created an object and that object (not a pointer to the object) and stored in variable person1.

                                 +--------------------------+
                                 | Person Object (Person 1) |
                                 |        name = Karan      |
                                 |                          |
                                 +--------------------------+
      
    • Now, when you assigned person2 = person1, there is something called Copy constructor is involved here.

    • It creates another object for person2 copying everything in person1 to person2.

                                 +--------------------------+
                                 | Person Object (Person1)  |
                                 |        name = Rajat      |
                                 |                          |
                                 +--------------------------+
      
                                 +--------------------------+
                                 | Person Object (Person2)  |
                                 |        name = Rajat      |
                                 |                          |
                                 +--------------------------+
      

    Hence, here we have two independent objects.

    • When you changed the value for one, the value got changed for only one, for the ones you actually wanted to change. And another independent object is as it was earlier.

                                 +--------------------------+
                                 | Person Object (Person1)  |
                                 |        name = Rajat      |
                                 |                          |
                                 +--------------------------+
      
                                 +--------------------------+
                                 | Person Object (Person2)  |
                                 |        name = Karan      |
                                 |                          |
                                 +--------------------------+