C ++中默认复制构造函数的奇怪行为

Weird behavior of default copy constructor in C++

我在学习 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,而不是它指向的字符数组。因此,更改对象 p2name 成员应该更改对象 p1name 成员。因此 p1.name 应该是 "Bill" 而不是 "Tom"

我的推理有什么问题?为什么打印 "Tom"?

By default, copying an object means copying its members

是的。

therefore while creating p2 object using default copy constructor it should copy merely a pointer name, not the character array it points to.

正确。

Therefore changing name member of object p2 should change the name member of object p1.

没有。是的,p2.namep1.name指向相同的内存位置,但这并不意味着改变p1.name的指针value会改变p2.name 的值。如果那是 ints,如果更改 p1.name 没有效果 p2.name,您会感到惊讶吗?因为这里也是一样的。您有两个不同的变量,更改其中一个的值不会更改另一个的值。

int a = 0;
int b = 1;

int* ptrA = &a;
int *ptrA2 = &a;

*ptrA = 1; // now a == 1
*ptrA2 = 4; // now a == 4

ptrA2 = &b;

*ptrA2 = 10; // now b == 10
*ptrA = 3; // now a == 3, a != 10