Creating a C++ object with and without new keyword

Viewed 171

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?

3 Answers

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      |
                               |                          |
                               +--------------------------+
    

In the first snippet, you have two pointers pointing two the same object which is dangerous, hence on using any of the two pointers to make a change you change the same object. Note that you have created only one object.

Person *person2 = person1;

The previous line creates a new pointer pointing to the same object pointed to by the pointer person1

While in the second snippet you have created person2 object which is different from person1 but has the same value for name data member (because you've used the copy ctor) and then you have changed the value of the name of person2, hence two different names.

Person person2 = person1;

The previous line creates a new object using copy actor, hence have the same values for the data members.

In the first case, you have pointers to Person which actually pointing to the same dynamically allocated object. Two pointers but there are no two separate objects. Therefore, changing the name will affect both.

In the second one, you do copy initialization and has created literally two distinct objects here.

Person person2 = person1;

Therefore you have different names after setting them.

Related