使用新关键字创建对象:
#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;
}
输出:卡兰卡兰
创建没有新关键字的对象:
#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;
}
输出:拉贾特卡兰
[我期望输出为[Karan Karan],正如我在Person person2 = person1
中所认为的,person2
指的是相同的person1
。但事实并非如此。有人可以解释一下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-----------> | |
+--------------------------+
是这样吗?
No!基本上只更改了它指向的对象。因此对于一个对象。实际上,从来没有两个对象,也从未创建过两个对象。它是由两个指针指向的同一对象。
在第二种情况下
您创建了一个对象和该对象(不是指向该对象的指针)并存储在变量person1
中。
+--------------------------+
| Person Object (Person 1) |
| name = Karan |
| |
+--------------------------+
现在,当您分配person2 = person1
时,这里涉及到一个称为复制构造函数。
它为person2
创建另一个对象,将person1
中的所有内容复制到person2
。
+--------------------------+
| Person Object (Person1) |
| name = Rajat |
| |
+--------------------------+
+--------------------------+
| Person Object (Person2) |
| name = Rajat |
| |
+--------------------------+
因此,这里有两个independent对象。*当您将值更改为1时,实际上只想更改一次,则该值仅更改了一次。还有另一个独立的对象,就像以前一样。
+--------------------------+
| Person Object (Person1) |
| name = Rajat |
| |
+--------------------------+
+--------------------------+
| Person Object (Person2) |
| name = Karan |
| |
+--------------------------+
在第一种情况下,您具有指向Person
的指针,该指针实际上指向同一动态分配的对象。两个指针,但是没有两个单独的对象。因此,更改名称将同时影响两者。
在第二个中,您执行copy initialization并在此处实际上创建了两个不同的对象。
Person person2 = person1;
因此设置它们后,您将使用不同的名称。
在第一个代码段中,有两个指针指向两个相同的对象,这很危险,因此,使用两个指针中的任何一个进行更改时,您都将更改同一对象。请注意,您仅创建了一个对象。
Person *person2 = person1;
上一行创建一个新的指针,该指针指向由指针person1
指向的同一对象
在第二个代码段中,您创建的person2
对象与person1
不同,但其name
数据成员的值相同(因为您使用了复制ctor),然后更改了name
的person2
,因此有两个不同的名称。
Person person2 = person1;
上一行使用copy actor创建了一个新对象,因此数据成员具有相同的值。