为何s1.name与s2.name地址不同,但修改s2.name却影响s1.name?
问题解答:为何修改s2.name内容会影响s1.name?
核心原因是默认拷贝构造函数的浅拷贝行为:
你没有给Student类定义拷贝构造函数,C++编译器会自动生成一个默认的拷贝构造函数。这个默认函数只会做简单的成员值复制——也就是把s1的每个成员变量的值直接拷贝给s2。
具体到你的代码:
s1.name是一个指针,指向堆上通过new分配的内存块(里面存着字符串"abcd")。- 默认拷贝构造函数把
s1.name的指针值直接复制给s2.name。这意味着:&s1.name和&s2.name是两个不同的地址(因为它们是两个不同对象的成员变量,存在栈上的不同位置);- 但
s1.name和s2.name这两个指针指向的是同一块堆内存。
所以当你执行s2.name[0] = 'e'时,实际是修改了这块共享堆内存里的内容,s1.name指向的也是这块内存,自然s1的输出也会跟着改变。
如果验证的话,你可以把输出指针自身地址的代码改成输出指针指向的地址:
cout << s1.name << endl; cout << s2.name << endl;
这时会发现两者输出的地址完全相同,就能直观看到它们指向同一块内存。
解决方法:实现深拷贝
给Student类手动定义拷贝构造函数,为s2的name重新分配一块堆内存,再把s1.name的内容复制过去,避免共享内存:
Student(const Student &other) { this->age = other.age; // 重新分配内存 this->name = new char[strlen(other.name) + 1]; // 复制内容 strcpy(this->name, other.name); }
这样修改s2.name的内容就不会影响s1了。
内容的提问来源于stack exchange,提问作者Prathamt
相关产品推荐
相关产品推荐

