关于位赋值运算符的疑问:为何对象赋值后修改未相互影响?
问题根源:默认赋值运算符的行为与你的类成员类型
嘿,我来给你把这个事儿掰明白:那个网站的表述只在特定场景下成立,而你的代码刚好没触发这个场景。
先纠正网站表述的局限性
它说的「赋值操作后两个对象共享同一内存地址,修改一个影响另一个」,本质是浅拷贝导致的问题,但这种情况只会发生在你的类包含指针、动态分配的内存或者其他需要手动管理的资源时。默认的赋值运算符(也就是你代码里用的b2 = b1)会做「成员逐值拷贝」,但对于指针来说,它只拷贝指针本身的地址,而不是指针指向的内容——这才会导致两个对象共享同一块堆内存。
看看你的类成员为什么不会触发这个问题
你的Base类里只有两种成员:
int age:这是值类型,赋值的时候会直接把b1.age的数值复制到b2.age的独立内存空间里。b1和b2的age完全是两块不相关的内存,修改b2的age自然不会影响b1。string name:std::string是C++标准库自带的类,它已经自己重载了赋值运算符。内部会处理动态内存的拷贝(要么是直接深拷贝,要么是现代实现的写时拷贝——但只要你修改其中一个string,它会立刻为自己分配独立的内存),所以两个对象的name底层也不会共享内存。
举个例子,让你看到网站说的情况
如果我们修改你的类,加入一个需要手动管理的指针成员,就能复现网站描述的问题:
#include <iostream> #include <cstring> using namespace std; class Base{ public: Base(const char* name) { this->name = new char[strlen(name)+1]; strcpy(this->name, name); } Base() : name(nullptr) {}; ~Base() { delete[] name; } // 注意这里要释放内存,不然会泄漏 void displayName() { cout << name << endl; } char* name; // 换成指针成员 }; int main() { Base b1("Alek"),b2; b2 = b1; // 默认赋值运算符,只拷贝指针地址 b1.displayName(); // 输出Alek strcpy(b2.name, "Bob"); // 修改b2的name指向的内存 b1.displayName(); // 现在会输出Bob,因为两个对象共享同一块内存 system("pause"); return 0; }
这个例子里,因为name是指针,默认赋值只拷贝了指针的值(也就是内存地址),所以b1和b2的name指向同一块堆内存,修改其中一个就会影响另一个。
回到你的代码总结
你的Base类没有任何需要手动管理的动态资源,默认赋值运算符做的是完全安全的成员拷贝,b1和b2是两个完全独立的对象,修改b2.age当然不会影响b1.age啦。
内容的提问来源于stack exchange,提问作者alek gholami
相关产品推荐
相关产品推荐

