使用和不使用 new 关键字创建 C++ 对象

Kar*_*tty 3 c++ class copy-constructor dynamic-memory-allocation c++17

使用 new 关键字创建对象:

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

Karan  
Karan
Run Code Online (Sandbox Code Playgroud)

创建没有 new 关键字的对象:

#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;
}
Run Code Online (Sandbox Code Playgroud)

输出:

Rajat  
Karan  
Run Code Online (Sandbox Code Playgroud)

我希望输出是 'Karan Karan' 正如我所想的那样Person person2 = person1person2指的是相同的person1. 但事实并非如此。

有人可以解释一下这条线Person person2 = person1在引擎盖下做什么吗?它是否创建了一个全新的对象?

Him*_*rma 5

让我们看看后台发生了什么。

第一种情况

  • 在使用new关键字时,new创建了一个对象并返回一个指向该对象的指针。

                               +--------------------------+
           person1 ----------> |    Person Object         |
                               |        name = Rajat      |
                               +--------------------------+
    
    Run Code Online (Sandbox Code Playgroud)
  • 然后将地址复制到另一个指向对象的指针中的对象。所以基本上现在两个指针都指向同一个对象。

                               +--------------------------+
           person1 ----------> |    Person Object         |
                               |        name = Rajat      |
           person2-----------> |                          |
                               +--------------------------+
    
    Run Code Online (Sandbox Code Playgroud)
  • 现在,您更改了name使用一个指针的值并更改了使用一个指针的值同时更改了person1person2

person2->setName("Karan")
Run Code Online (Sandbox Code Playgroud)
                               +--------------------------+
           person1 ----------> |    Person Object         |
                               |        name = Karan      |
           person2-----------> |                          |
                               +--------------------------+
Run Code Online (Sandbox Code Playgroud)

是这样吗??

不!基本上它只改变了它指向的对象。因此对于一个对象。事实上,从来没有两个对象,两个对象从来没有被创建过。它是由两个指针指向的同一个对象。

第二种情况

  • 您创建了一个对象和该对象(不是指向该对象的指针)并存储在变量中person1

                               +--------------------------+
                               | Person Object (Person 1) |
                               |        name = Karan      |
                               |                          |
                               +--------------------------+
    
    Run Code Online (Sandbox Code Playgroud)
  • 现在,当您分配 时person2 = person1,这里涉及一种称为复制构造函数的东西。

  • 它创建了另一个对象,用于person2将所有内容复制person1person2.

                               +--------------------------+
                               | Person Object (Person1)  |
                               |        name = Rajat      |
                               |                          |
                               +--------------------------+
    
                               +--------------------------+
                               | Person Object (Person2)  |
                               |        name = Rajat      |
                               |                          |
                               +--------------------------+
    
    Run Code Online (Sandbox Code Playgroud)

因此,这里我们有两个独立的对象。

  • 当您更改 1 的值时,仅更改了 1 的值,即您实际想要更改的值。另一个独立的对象和之前一样。

                               +--------------------------+
                               | Person Object (Person1)  |
                               |        name = Rajat      |
                               |                          |
                               +--------------------------+
    
                               +--------------------------+
                               | Person Object (Person2)  |
                               |        name = Karan      |
                               |                          |
                               +--------------------------+
    
    Run Code Online (Sandbox Code Playgroud)

  • C++ 为您提供这种选择的事实是它的优势之一,也是它比我们提到的其他语言更复杂的原因。 (3认同)