C++重载*运算符实现字符串重复功能未生效问题咨询
问题根因
- 最直接的逻辑错误:你实现的
operator*是const成员函数,不会修改当前实例,只会返回一个内容为原字符串重复n次的全新Mystring对象。你在main中写s3*5;时,确实生成了重复5次的临时对象,但没有将这个返回值赋值给任何变量,临时对象执行完该行就直接销毁,原s3从未被修改,打印自然还是原始值abcdef。 - 基础语法错误:头文件中Mystring类定义末尾缺少分号,编译阶段会直接报错。
- 必现的内存错误:你的类管理堆上的char数组,但没有实现析构函数、深拷贝构造函数、拷贝赋值运算符,返回临时对象时会发生浅拷贝,导致悬垂指针、重复释放、内存泄漏问题。
- 功能覆盖不全:当前仅实现了成员版本的
operator*,只支持Mystring对象 * int的调用顺序,不支持int * Mystring对象的写法。
修复步骤
- 补全Mystring类的基础构造、析构、深拷贝逻辑,解决内存问题
- 修正main函数的调用逻辑,要么接收
operator*返回的新对象,要么额外实现*=运算符支持原地修改 - (可选)实现全局版本的
operator*支持整数在前的调用顺序
修正后完整代码
头文件部分
#include <iostream> #include <cstring> class Mystring { friend std::ostream &operator<<(std::ostream &os, const Mystring &rhs); friend std::istream &operator>>(std::istream &in, Mystring &rhs); // 全局operator*支持int * Mystring的写法 friend Mystring operator*(int n, const Mystring& s); private: char *str; public: Mystring(const char* s = ""); Mystring(const Mystring& other); ~Mystring(); Mystring& operator=(const Mystring& rhs); Mystring operator*(int n) const; Mystring& operator*=(int n); };
实现部分
// 普通构造 Mystring::Mystring(const char* s) { size_t len = std::strlen(s); str = new char[len + 1]; std::strcpy(str, s); } // 深拷贝构造 Mystring::Mystring(const Mystring& other) { size_t len = std::strlen(other.str); str = new char[len + 1]; std::strcpy(str, other.str); } // 析构 Mystring::~Mystring() { delete [] str; } // 拷贝赋值 Mystring& Mystring::operator=(const Mystring& rhs) { if (this == &rhs) return *this; delete [] str; size_t len = std::strlen(rhs.str); str = new char[len + 1]; std::strcpy(str, rhs.str); return *this; } // 字符串重复*运算符 Mystring Mystring::operator * (int n) const { // 处理n<=0的边界情况,直接返回空字符串 if (n <= 0) return Mystring{""}; size_t orig_len = std::strlen(str); size_t buff_size = orig_len * n + 1; char *buff = new char[buff_size]; buff[0] = '\0'; // 初始化空字符串,比strcpy效率高 for (int i = 0; i < n; i++) std::strcat(buff, str); Mystring temp{buff}; delete [] buff; return temp; } // 支持int在左侧的全局operator* Mystring operator*(int n, const Mystring& s) { return s * n; } // *=复合赋值运算符,支持原地修改 Mystring& Mystring::operator*=(int n) { *this = *this * n; return *this; } // 输出运算符 std::ostream& operator<<(std::ostream &os, const Mystring &rhs) { os << rhs.str; return os; } // 输入运算符 std::istream& operator>>(std::istream &in, Mystring &rhs) { char temp_buff[2048]; in >> temp_buff; rhs = Mystring{temp_buff}; return in; }
main函数调用示例
int main(){ Mystring s3{"abcdef"}; // 写法1:接收返回的新对象,不改动原s3 Mystring repeated = s3 * 5; std::cout << repeated << std::endl; // 输出:abcdefabcdefabcdefabcdefabcdef // 写法2:用*=直接修改原对象 s3 *= 5; std::cout << s3 << std::endl; // 输出:abcdefabcdefabcdefabcdefabcdef // 支持整数在前的写法 Mystring repeated2 = 3 * s3; std::cout << repeated2 << std::endl; return 0; }
内容的提问来源于stack exchange,提问作者Ahmed Elhossary
相关产品推荐
相关产品推荐

