为何重载的Copy Assignment Operator未被调用?附代码与修正方案
为什么重载的拷贝赋值运算符没被调用?
嘿,这个问题其实是C++里指针和对象的常见误区!咱们一步步拆解:
原代码的核心问题:你赋值的是指针,不是对象本身
看你原main里的这段代码:
String* s1 = new String("Hello"); String* s2 = new String("World"); s2 = s1; // 这里根本没调用对象的赋值运算符!
这里s1和s2都是指向String对象的指针,不是String对象本身。s2 = s1做的事情只是把s1存储的内存地址拷贝给s2——简单说就是让两个指针现在指向同一个String对象(原来s1指向的那个"Hello"对象),完全没碰对象的赋值运算符。
这就解释了为什么你重载的operator=里的cout从来没输出:因为这个函数根本没被调用过!而你看到s2->showData()输出"Hello",只是因为s2现在和s1指向同一个对象而已,同时原来s2指向的"World"对象因为没有指针指向它了,还会造成内存泄漏。
另外原代码还有几个隐藏bug:
- 带参构造函数里
data{(char*)s}直接把指针指向字符串字面量,而字符串字面量存在只读内存区,后续delete [] data会触发未定义行为 showData()函数返回*data是单个char,但你声明的返回类型是char*,这会编译报错
修正后的代码为什么能正常工作?
你更新后的代码做了几个关键改变:
String a("A: Hello"); String b("B: World"); b = a; // 这里才是真正调用对象的赋值运算符!
这里a和b是栈上的String对象,不是指针。b = a是直接对两个String对象进行赋值操作,这时候才会触发你重载的operator=,所以你能看到"Assignment"的输出。
除此之外,修正后的代码补全了C++类的必要函数,解决了原代码的其他问题:
- 空构造函数初始化
data为nullptr,避免后续delete野指针 - 带参构造函数正确分配内存并拷贝字符串,不再直接指向只读的字面量
- 赋值运算符加了自赋值检查(
if (&s != this)),避免自己赋值给自己时误删内存 - 析构函数释放
data指向的内存,防止内存泄漏 - 拷贝构造函数的实现(虽然用
*this = other的写法不算最高效,但能正确工作)
额外提示:如果一定要用指针怎么办?
如果你的场景必须使用动态分配的对象(指针),要调用对象的赋值运算符,得对指针指向的对象进行操作,也就是用解引用:
*s2 = *s1; // 这才会调用String的operator=
这样就会触发你重载的赋值运算符,而不是单纯的指针地址拷贝。
总的来说,优先使用栈对象而非动态指针,能减少很多内存管理的麻烦,也能避免这类指针操作的误区~
内容的提问来源于stack exchange,提问作者gath
相关产品推荐
相关产品推荐

