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

C++自定义MyString类重载>>运算符动态读取cin输入且不依赖std::string

问题根因

  • 运算符参数错误:重载operator>>需要修改传入的MyString实例,你给参数加了const修饰,属于逻辑错误,且str成员是私有属性,const实例无法修改。
  • 缓冲区未初始化/空间不足:直接调用is >> other.str时,要求str指向一块预先分配的、足够容纳输入内容的内存空间。你的str大概率是未初始化的野指针,或者分配的空间远小于输入的字符串长度,写入越界直接触发堆损坏。

不依赖std::string的实现方案

核心思路是逐个读取输入流的字符,动态扩容内部缓冲区,完全自主管理内存,实现代码如下:

#include <iostream>
// 如果不想引入cctype,可以自行实现空白符判断逻辑,替换下方的std::isspace调用即可
#include <cctype>

class MyString
{
private:
    char* str = nullptr;
    size_t length = 0;
    size_t capacity = 0; // 记录缓冲区实际可用大小

    // 内部扩容函数
    void reserve(size_t new_cap) {
        if (new_cap <= capacity) return;
        char* new_buf = new char[new_cap];
        // 拷贝原有内容
        for (size_t i = 0; i < length; i++) {
            new_buf[i] = str[i];
        }
        // 释放旧内存
        delete[] str;
        str = new_buf;
        capacity = new_cap;
    }

public:
    // 默认构造
    MyString() = default;

    // 析构函数,必须实现避免内存泄漏
    ~MyString() {
        delete[] str;
    }

    // 可选:获取C风格字符串接口
    const char* c_str() const {
        return str ? str : "";
    }

    size_t size() const {
        return length;
    }

    friend std::istream& operator>>(std::istream& is, MyString& other)
    {
        // 先清空原有内容
        other.length = 0;
        // 初始分配16字节缓冲区,可按需调整初始大小
        if (other.capacity < 16) {
            other.reserve(16);
        }

        char ch;
        // 跳过开头的空白符,和标准cin>>行为对齐
        while (is.get(ch) && std::isspace(static_cast<unsigned char>(ch))) {}

        // 读取内容直到遇到空白符或流结束
        while (is && !std::isspace(static_cast<unsigned char>(ch))) {
            // 空间不足时扩容为原来的2倍
            if (other.length + 1 >= other.capacity) {
                other.reserve(other.capacity * 2);
            }
            other.str[other.length++] = ch;
            is.get(ch);
        }
        // 补字符串结束符
        if (other.str) {
            other.str[other.length] = '\0';
        }

        // 如果是因为遇到空白符停止,把空白符放回输入流
        if (is) {
            is.unget();
        }

        return is;
    }
};

注意事项

  • 你需要自行实现拷贝构造函数、拷贝赋值运算符、移动构造、移动赋值函数,避免浅拷贝导致的double free、内存泄漏问题,符合C++三五法则要求。
  • 如果需要支持读取包含空格的整行内容,可以修改判断逻辑,把停止条件从遇到空白符改为遇到换行符即可,和std::getline行为对齐。

内容的提问来源于stack exchange,提问作者Alex Cai

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 23:57:03