重载流提取运算符报错:无效二元表达式操作数
解决Mystring类流提取运算符重载的问题
先直接分析你遇到的两个核心问题:
is >> buff报错:这个错误通常是编译器无法匹配到std::istream与char*的operator>>重载,虽然标准库提供了该重载,但可能是头文件缺失(比如未包含<cstring>)或环境问题。更稳妥的方案是放弃手动管理char数组,改用std::string作为临时缓冲区,既安全又能自动处理内存。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
相关产品推荐
相关产品推荐

