记录一下学习拷贝构造函数遇到的坑(深拷贝、浅拷贝)

1.先扔一个正常的拷贝构造函数

class A 
{
public:
    A(int a) { 
        this->a = new int(a); 
    }

    //A(const A &copy) { this->a = new int((copy.a)); }

    A(const A& other) {
        //this->a = new int(*(other.a)); // 深拷贝成员变量
        this->a = new int;
        *a = *(other.a);// 深拷贝成员变量
    }


    ~A() { delete a; }

public:
    int *a;
};

main 函数

int main()
{
    A obj_a(5);
    A obj_b(obj_a); // 使用深拷贝构造函数

    printf("对象\n");
    printf("obj_a %p\n", &obj_a);
    printf("obj_b %p\n", &obj_b);

    printf("成员变量\n");
    printf("obj_a :a %p\n", &(obj_a.a));
    printf("obj_b :a %p\n", &(obj_b.a));

    printf("obj_a :a %d\n", *(obj_a.a));
    printf("obj_b :a %d\n", *(obj_b.a));

    *(obj_a.a) = 8;
    printf("obj_a :a %d\n", *(obj_a.a));
    printf("obj_b :a %d\n", *(obj_b.a));

    return 0;
}

运行结果

对象
obj_a 001DF890
obj_b 001DF884
成员变量
obj_a :a 001DF890
obj_b :a 001DF884
obj_a :a 5
obj_b :a 5
obj_a :a 8
obj_b :a 5

在预料之中,成员变量地址不同,值也不会相互影响;

2.接下来我想测试一下堆空间的拷贝 (new对象)

main函数

int main()
{
    A *obj_a = new A(6);
    A* obj_b(obj_a);

    printf("对象\n");
    printf("obj_a %p\n", &obj_a);
    printf("obj_b %p\n", &obj_b);

    printf("成员变量\n");
    printf("obj_a :a %p\n", &(obj_a->a));
    printf("obj_b :a %p\n", &(obj_b->a));

    printf("obj_a :a %d\n", *(obj_a->a));
    printf("obj_b :a %d\n", *(obj_b->a));

    *(obj_a->a) = 8;
    printf("obj_a :a %d\n", *(obj_a->a));
    printf("obj_b :a %d\n", *(obj_b->a));

    delete obj_a;
    //delete obj_b;   //这里会报错

    return 0;
}

运行结果

对象
obj_a 008FFA94
obj_b 008FFA88
成员变量
obj_a :a 00F1B498
obj_b :a 00F1B498
obj_a :a 6
obj_b :a 6
obj_a :a 8
obj_b :a 8

很奇怪,为什么a的地址一样,打断点发现没有进入到拷贝构造函数,可以自己试一试

做一点小改变

mian函数

    A *obj_a = new A(6);
    A* obj_b = new A(*obj_a); // 使用拷贝构造函数进行初始化

    printf("对象\n");
    printf("obj_a %p\n", &obj_a);
    printf("obj_b %p\n", &obj_b);

    printf("成员变量\n");
    printf("obj_a :a %p\n", &(obj_a->a));
    printf("obj_b :a %p\n", &(obj_b->a));

    printf("obj_a :a %d\n", *(obj_a->a));
    printf("obj_b :a %d\n", *(obj_b->a));

    *(obj_a->a) = 8;
    printf("obj_a :a %d\n", *(obj_a->a));
    printf("obj_b :a %d\n", *(obj_b->a));

    delete obj_a;
    delete obj_b;   //这里也不会报错了

    return 0;

运行结果

对象
obj_a 00CFF844
obj_b 00CFF838
成员变量
obj_a :a 0107B498
obj_b :a 0107B4F8
obj_a :a 6
obj_b :a 6
obj_a :a 8
obj_b :a 6

确认无疑是深拷贝了,a的地址不同。

3.这里解释一下为什么

 首先A* obj_b      obj_b是一个指针变量,这里涉及到指针的复制和对象的构造。这行代码实际上是将 obj_b 的指针指向了与 obj_a 相同的内存地址。它没有创建新的对象,只是将指针复制给了 obj_b,因此没有涉及到拷贝构造函数的调用(或者说使用了指针的默认拷贝构造函数)。obj_a 和 obj_b 现在都指向相同的内存。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值