You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++自定义stringTest类operator+返回垃圾数据求助

问题根源:缺失赋值运算符导致的浅拷贝问题

你遇到的核心问题是没有重载赋值运算符operator=,编译器生成的默认赋值运算符会执行浅拷贝,具体触发过程如下:

  1. operator+创建的临时对象temp拥有一块堆内存,存储着拼接后的正确字符串;
  2. 执行string3 = s1+s2;时,默认赋值运算符直接把临时对象的p指针值拷贝给string3.p,两者指向同一块内存;
  3. 临时对象在赋值完成后被销毁,调用析构函数~stringTest()释放了这块内存;
  4. 后续访问string3.p时,它已经是野指针,指向的内存已被系统回收,因此输出垃圾字符。

解决方案:重载赋值运算符实现深拷贝

在stringTest类的public区域添加以下operator=的重载代码:

stringTest& operator=(const stringTest& s) {
    // 处理自赋值,避免重复释放自身内存
    if (this == &s) {
        return *this;
    }
    // 先释放当前对象已占用的堆内存
    delete[] p;
    // 深拷贝新对象的长度和字符串内容
    len = s.len;
    p = new char[len + 1];
    strcpy(p, s.p);
    return *this;
}

额外优化建议

  1. 修改show函数的参数传递方式:当前show函数使用值传递,会触发拷贝构造函数产生额外内存开销,改成const引用传递更高效:
// 类声明部分
friend void show(const stringTest& s);
// 实现部分
void show(const stringTest& s) {
    cout << s.p;
}
  1. 优化operator<=函数:没必要调用strlen,类中已经维护了len成员变量,直接使用即可,还能避免空指针风险(比如默认构造的对象p为nullptr时,strlen会触发崩溃):
int operator<=(const stringTest& s, const stringTest& t) {
    return s.len <= t.len ? 1 : 0;
}

修改后的完整代码

#include<iostream>
#include<string.h>

class stringTest
{
    char* p;
    int len;
public:
    stringTest() { len = 0; p = nullptr; }
    stringTest(const char* s);
    stringTest(const stringTest& s);
    ~stringTest() { delete[] p; }

    stringTest& operator=(const stringTest& s);
    friend stringTest operator+(const stringTest& s, const stringTest& t);
    friend int operator<=(const stringTest& s, const stringTest& t);
    friend void show(const stringTest& s);
};

stringTest::stringTest(const char* s)
{
    len = strlen(s);
    p = new char[len + 1];
    strcpy(p, s);
}
stringTest::stringTest(const stringTest& s)
{
    len = s.len;
    p = new char[len + 1];
    strcpy(p, s.p);
}

stringTest& stringTest::operator=(const stringTest& s) {
    if (this == &s) {
        return *this;
    }
    delete[] p;
    len = s.len;
    p = new char[len + 1];
    strcpy(p, s.p);
    return *this;
}

stringTest operator+(const stringTest &s, const stringTest &t)
{
    stringTest temp;
    temp.len = s.len + t.len;
    temp.p = new char[temp.len + 1];
    strcpy(temp.p, s.p);
    strcat(temp.p, t.p);
    return temp;
}
int operator<=(const stringTest& s, const stringTest& t)
{
    return s.len <= t.len ? 1 : 0;
}

void show(const stringTest& s)
{
    std::cout << s.p;
}


int main()
{
    stringTest s1 = "New ";
    stringTest s2 = "York";
    stringTest s3 = "Delhi";
    stringTest string1, string2, string3;
    string1 = s1;
    string2 = s2;
    string3 = s1+s2;

    std::cout << "\nstring1 = "; show(string1);
    std::cout << "\nstring2 = "; show(string2);
    std::cout << "\n";
    std::cout << "\nstring3 = "; show(string3);
    std::cout << "\n\n";
    if (string1 <= string3)
    {
        show(string1);
        std::cout << " smaller than ";
        show(string3);
        std::cout << "\n";
    }
    else
    {
        show(string3);
        std::cout << " smaller than ";
        show(string1);
        std::cout << "\n";
    }
    return 0;
}

内容的提问来源于stack exchange,提问作者Vivek Gaur

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 18:30:16