事关赋值运算符和复制运算符的区别。
请看下面的代码样例。

重载赋值运算符

HelloWorld& operator=(const HelloWorld& other){
    cout<<"~overload"<<endl;
    if (this != &other){
        *ptr = *other.ptr;
    }
    return *this;
}

赋值方法1(出问题的写法)

simple_audio::HelloWorld a = simple_audio::HelloWorld();
*a.ptr = 30;

simple_audio::HelloWorld b = a;
cout<< "a->ptr => " << a.ptr <<endl;
*a.ptr = 40;
cout<< "b->ptr => " << b.ptr << "=>" << *b.ptr <<endl;

输出结果:

a->ptr => 0x1e409cf05f0
b->ptr => 0x1e409cf05f0=>40

这里没有打印输出~overload, 说明重载赋值运算符那个方法没有执行。
并且两个指针指向了同一个地址,说明发生了浅拷贝。

赋值方法2(没出问题)

simple_audio::HelloWorld a = simple_audio::HelloWorld();
*a.ptr = 30;

simple_audio::HelloWorld b;
b = a;
cout<< "a->ptr => " << a.ptr <<endl;
*a.ptr = 40;
cout<< "b->ptr => " << b.ptr << "=>" << *b.ptr <<endl;

结果:

~overload
a->ptr => 0x1cd8fc106e0
b->ptr => 0x1cd8fc10790=>30

这里执行了,并且没有发生浅拷贝。

原因

写法1进行对象初始化操作,直接调用复制运算符。而写法2是对对象b初始化后,对对象b赋值a,调用的是赋值运算符。所以写法1的时候需要重载复制运算符。

HelloWorld(const HelloWorld& other){
    cout<<"~~resign"<<endl;
    this->ptr = new int(*other.ptr);
}

结果

~~resign
a->ptr => 0x21f0011c350
b->ptr => 0x21f0011c380=>30
最后修改:2024 年 04 月 01 日
如果觉得我的文章对你有用,请随意赞赏