【发布时间】:2018-01-06 19:52:32
【问题描述】:
在学习 C++ 中的隐式复制构造函数时,我遇到了一个奇怪的行为。这是关于这堆代码的:
#include <iostream>
class Person
{
public:
char* name;
int age;
Person( const char* the_name, int the_age )
{
name = new char[strlen( the_name ) + 1];
strcpy( name, the_name );
age = the_age;
}
~Person()
{
delete[] name;
}
};
int main(){
Person p1( "Tom", 22 );
Person p2( p1 );
p2.name = "Bill";
// the output is: "Tom"
std::cout << p1.name << std::endl;
std::cin.get();
}
默认情况下,复制一个对象意味着复制其成员,因此在使用默认复制构造函数创建p2 对象时,它应该只复制一个指针name,而不是它指向的字符数组。因此更改对象p2 的name 成员应该更改对象p1 的name 成员。因此p1.name 应该是"Bill" 而不是"Tom"。
我的推理有什么问题?为什么要打印"Tom"?
【问题讨论】:
-
它正在打印
Tom,因为这是p1.name所指向的。将p2.name指向其他地方并不会改变这一点。不过请阅读rule of zero。它将防止许多此类错误。 -
是的,子对象是指针
name,而不是name指向的任何东西......如果我在我的财产上放置一个指向附近湖的标志,这并不意味着我拥有这个湖。最多我拥有这个标志。 -
你不会改变
p1.name指向的内存。您的 C++ 书是否没有说明为什么使用strcpy复制 C 字符串? -
您似乎将指针与引用混淆了。
p2.name不是对p1.name的引用,它只是一个最初指向与p1.name相同地址的指针。重新分配一个不会影响另一个。 -
拿一张纸。在两个角写上“Tom”和“Bill”。在其他角落用 p1.name 和 p2.name 绘制圆圈。在这些圆圈附近绘制指向“汤姆”的小箭头。这些是您的指针,箭头是它们的值。现在擦除 p2 圆圈中的箭头并绘制新的箭头,指向“Bill”。您重新分配了 p2 指针。现在,角落里写着什么,p1箭头指向的是什么?
标签: c++ object constructor copy implicit