使用和不使用 new 关键字创建 C++ 对象
Creating a C++ object with and without new keyword
正在使用 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;
}
输出:
Karan
Karan
创建一个没有 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;
}
输出:
Rajat
Karan
我预计输出是 'Karan Karan',正如我在 Person person2 = person1
中所想的那样,person2
指的是相同的 person1
。但事实并非如此。
谁能解释一下 Person person2 = person1
行在幕后做了什么?它会创建一个全新的对象吗?
在第一个片段中,您有两个指针指向两个相同的对象,这是危险的,因此在使用两个指针中的任何一个进行更改时,您更改的是同一个对象。请注意,您只创建了一个对象。
Person *person2 = person1;
上一行创建了一个新的指针,指向指针指向的同一个对象person1
虽然在第二个代码段中您创建了 person2
对象,它不同于 person1
但具有与 name
数据成员相同的值(因为您使用了复制构造函数) 然后您更改了 person2
的 name
的值,因此有两个不同的名称。
Person person2 = person1;
上一行使用复制角色创建了一个新对象,因此数据成员具有相同的值。
在第一种情况下,您有指向 Person
的指针,它实际上指向同一个动态分配的对象。两个指针,但没有两个单独的对象。因此,更改名称将影响两者。
在第二个中,您执行 copy initialization 并在此处创建了两个不同的对象。
Person person2 = person1;
所以你设置的名字不一样
让我们看看后台发生了什么。
第一种情况
在使用 new
关键字时,new
创建了一个对象并返回了指向该对象的指针。
+--------------------------+
person1 ----------> | Person Object |
| name = Rajat |
+--------------------------+
然后您将地址复制到另一个对象指针中的对象。所以基本上现在两个指针都指向同一个对象。
+--------------------------+
person1 ----------> | Person Object |
| name = Rajat |
person2-----------> | |
+--------------------------+
现在,您使用一个指针更改了 name
的值,并且使用一个指针更改了值同时更改了 person1
和 person2
。
person2->setName("Karan")
+--------------------------+
person1 ----------> | Person Object |
| name = Karan |
person2-----------> | |
+--------------------------+
是吗??
不! 基本上它只针对它指向的对象进行了更改。因此对于一个对象。事实上,从来没有两个对象,从来没有创建过两个对象。这是两个指针指向的同一个对象。
第二种情况
您创建了一个对象和该对象(不是指向该对象的指针)并存储在变量 person1
.
+--------------------------+
| Person Object (Person 1) |
| name = Karan |
| |
+--------------------------+
现在,当你分配person2 = person1
时,这里涉及到一个叫做复制构造函数的东西。
它为 person2
创建另一个对象,将 person1
中的所有内容复制到 person2
。
+--------------------------+
| Person Object (Person1) |
| name = Rajat |
| |
+--------------------------+
+--------------------------+
| Person Object (Person2) |
| name = Rajat |
| |
+--------------------------+
因此,这里我们有两个独立对象。
当您更改一个的值时,该值只更改了一个,即您真正想要更改的值。另一个独立的对象和之前一样。
+--------------------------+
| Person Object (Person1) |
| name = Rajat |
| |
+--------------------------+
+--------------------------+
| Person Object (Person2) |
| name = Karan |
| |
+--------------------------+
正在使用 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;
}
输出:
Karan
Karan
创建一个没有 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;
}
输出:
Rajat
Karan
我预计输出是 'Karan Karan',正如我在 Person person2 = person1
中所想的那样,person2
指的是相同的 person1
。但事实并非如此。
谁能解释一下 Person person2 = person1
行在幕后做了什么?它会创建一个全新的对象吗?
在第一个片段中,您有两个指针指向两个相同的对象,这是危险的,因此在使用两个指针中的任何一个进行更改时,您更改的是同一个对象。请注意,您只创建了一个对象。
Person *person2 = person1;
上一行创建了一个新的指针,指向指针指向的同一个对象person1
虽然在第二个代码段中您创建了 person2
对象,它不同于 person1
但具有与 name
数据成员相同的值(因为您使用了复制构造函数) 然后您更改了 person2
的 name
的值,因此有两个不同的名称。
Person person2 = person1;
上一行使用复制角色创建了一个新对象,因此数据成员具有相同的值。
在第一种情况下,您有指向 Person
的指针,它实际上指向同一个动态分配的对象。两个指针,但没有两个单独的对象。因此,更改名称将影响两者。
在第二个中,您执行 copy initialization 并在此处创建了两个不同的对象。
Person person2 = person1;
所以你设置的名字不一样
让我们看看后台发生了什么。
第一种情况
在使用
new
关键字时,new
创建了一个对象并返回了指向该对象的指针。+--------------------------+ person1 ----------> | Person Object | | name = Rajat | +--------------------------+
然后您将地址复制到另一个对象指针中的对象。所以基本上现在两个指针都指向同一个对象。
+--------------------------+ person1 ----------> | Person Object | | name = Rajat | person2-----------> | | +--------------------------+
现在,您使用一个指针更改了
name
的值,并且使用一个指针更改了值同时更改了person1
和person2
。
person2->setName("Karan")
+--------------------------+
person1 ----------> | Person Object |
| name = Karan |
person2-----------> | |
+--------------------------+
是吗??
不! 基本上它只针对它指向的对象进行了更改。因此对于一个对象。事实上,从来没有两个对象,从来没有创建过两个对象。这是两个指针指向的同一个对象。
第二种情况
您创建了一个对象和该对象(不是指向该对象的指针)并存储在变量
person1
.+--------------------------+ | Person Object (Person 1) | | name = Karan | | | +--------------------------+
现在,当你分配
person2 = person1
时,这里涉及到一个叫做复制构造函数的东西。它为
person2
创建另一个对象,将person1
中的所有内容复制到person2
。+--------------------------+ | Person Object (Person1) | | name = Rajat | | | +--------------------------+ +--------------------------+ | Person Object (Person2) | | name = Rajat | | | +--------------------------+
因此,这里我们有两个独立对象。
当您更改一个的值时,该值只更改了一个,即您真正想要更改的值。另一个独立的对象和之前一样。
+--------------------------+ | Person Object (Person1) | | name = Rajat | | | +--------------------------+ +--------------------------+ | Person Object (Person2) | | name = Karan | | | +--------------------------+