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

重载流提取运算符报错:无效二元表达式操作数

解决Mystring类流提取运算符重载的问题

先直接分析你遇到的两个核心问题:

  1. is >> buff报错:这个错误通常是编译器无法匹配到std::istream与char*的operator>>重载,虽然标准库提供了该重载,但可能是头文件缺失(比如未包含<cstring>)或环境问题。更稳妥的方案是放弃手动管理char数组,改用std::string作为临时缓冲区,既安全又能自动处理内存。
  2. is >> *buff只读取单个字符:因为*buff是char类型,std::istream的operator>>对char的行为就是读取单个字符,所以只会拿到输入的第一个字符。

正确的流提取运算符实现

推荐用std::string作为中间存储,既不需要手动分配内存,也能避免缓冲区溢出风险,同时和标准库的字符串读取行为保持一致:

#include <iostream>
#include <string>  // 必须包含此头文件
#include "mystring.h"

std::istream &operator>>(std::istream &is, Mystring &obj) {
    std::string temp_str;
    // 读取到空白符为止(和std::cin >> std::string行为一致)
    is >> temp_str;

    // 检查读取是否成功(比如输入流是否处于有效状态)
    if (is) {
        // 利用Mystring的const char*构造函数赋值
        obj = Mystring{temp_str.c_str()};
    } else {
        // 读取失败时重置对象为空白状态
        obj = Mystring{};
    }

    return is;
}

如果需要读取包含空格的完整一行字符串,改用std::getline即可,注意要处理可能残留的换行符:

std::istream &operator>>(std::istream &is, Mystring &obj) {
    std::string temp_str;
    // 跳过之前可能残留的换行符(比如cin >> 操作后的换行)
    if (is.peek() == '\n') {
        is.ignore();
    }
    // 读取整行,直到换行符
    std::getline(is, temp_str);

    if (is) {
        obj = Mystring{temp_str.c_str()};
    } else {
        obj = Mystring{};
    }

    return is;
}

确保Mystring类的配套实现

要让上面的代码正常工作,你的Mystring类需要具备以下核心成员:

  • 接受const char*的构造函数
  • 正确的赋值运算符(避免浅拷贝)
  • 析构函数(释放动态分配的内存)
  • 流输出运算符重载(才能用std::cout << name)

示例实现如下:

// 在mystring.h中补充
#include <cstring>

class Mystring {
private:
    char* cstring;
    size_t size;

public:
    // 默认构造函数(空字符串)
    Mystring() : cstring(new char[1]()), size(0) {}

    // const char*构造函数
    Mystring(const char* str) : size(std::strlen(str)) {
        cstring = new char[size + 1];
        std::strcpy(cstring, str);
    }

    // 拷贝构造函数(可选,但建议实现避免浅拷贝)
    Mystring(const Mystring& other) : size(other.size) {
        cstring = new char[size + 1];
        std::strcpy(cstring, other.cstring);
    }

    // 赋值运算符
    Mystring& operator=(const Mystring& other) {
        if (this != &other) { // 防止自赋值
            delete[] cstring;
            size = other.size;
            cstring = new char[size + 1];
            std::strcpy(cstring, other.cstring);
        }
        return *this;
    }

    // 析构函数
    ~Mystring() {
        delete[] cstring;
    }

    // 流输出运算符重载
    friend std::ostream& operator<<(std::ostream& os, const Mystring& str) {
        os << str.cstring;
        return os;
    }

    friend std::istream &operator>>(std::istream &is, Mystring &str);
};

测试验证

用你提供的测试代码:

Mystring name;
std::cout << "name: " << std::endl;
std::cin >> name;
std::cout << "Your name is " << name;

如果用第一种读取到空白符的实现,输入harry会输出Your name is harry;如果用getline的实现,输入harry potter会完整输出Your name is harry potter。

内容的提问来源于stack exchange,提问作者elfarouk kamal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 03:50:48