使用智能指针实现自定义字符串类时的运算符[]及类型转换错误解决求助
使用智能指针实现自定义字符串类时的运算符[]及类型转换错误解决求助
看起来你在实现自定义字符串类的时候踩了std::shared_ptr的两个常见坑,我来帮你一步步拆解并解决这些问题:
先分析错误原因
no suitable conversion function from "std::shared_ptr<char>" to "void *" exists
你在调用memcpy时直接传递了shared_ptr<char>对象,但memcpy需要的是原始的void*指针类型。另外这里还有个更关键的问题:你用make_shared<char>(size+1)其实是在分配单个char元素,并把它的值初始化为size+1,而不是分配一个能容纳size+1个char的数组——这完全不符合你存储字符串的需求!no operator "[]" matches these operandsstd::shared_ptr<char>(指向单个char的智能指针)并没有重载[]运算符,只有std::shared_ptr<char[]>(专门用于管理char数组的智能指针)才支持通过[]直接访问数组元素。
修正后的完整代码
#include <iostream> #include <memory> #include <cstring> #include <stdexcept> // 用于越界异常 class Mystring { private: unsigned int size; // 改为管理char数组的shared_ptr std::shared_ptr<char[]> message; public: // 普通构造函数 Mystring(const char* input) : size(std::strlen(input)), message(std::make_shared<char[]>(size + 1)) { std::cout << "Created" << std::endl; // 用get()获取底层原始指针传给memcpy std::memcpy(this->message.get(), input, size + 1); } // 拷贝构造函数 Mystring(const Mystring& other) : size(other.size), message(std::make_shared<char[]>(size + 1)) { std::cout << "Copied" << std::endl; // 改成Copied更易区分构造类型 std::memcpy(this->message.get(), other.message.get(), size + 1); } ~Mystring() { std::cout << "Deleted" << std::endl; } // 重载输出运算符 friend std::ostream& operator<<(std::ostream& Cout, const Mystring& mystring) { // 同样用get()获取char*指针,让cout正确输出字符串 Cout << mystring.message.get() << std::endl; return Cout; } // 非const版本的operator[],支持修改元素 char& operator[](const unsigned int index) { // 新增越界检查,避免非法访问 if (index >= size) throw std::out_of_range("Mystring index out of bounds"); return this->message[index]; } // const版本的operator[],支持const对象访问 const char& operator[](const unsigned int index) const { if (index >= size) throw std::out_of_range("Mystring index out of bounds"); return this->message[index]; } }; // 测试代码 int main() { try { Mystring s1("Hello World"); std::cout << s1; s1[0] = 'h'; std::cout << s1; Mystring s2 = s1; std::cout << s2; // 测试越界检查 // s1[20] = 'x'; } catch (const std::exception& e) { std::cerr << "Error: " << e.what() << std::endl; } return 0; }
关键修改点说明
- 智能指针类型调整:把
std::shared_ptr<char>改为std::shared_ptr<char[]>,这是核心修复。数组版本的shared_ptr会自动用delete[]释放内存,避免单个元素版本用delete释放数组导致的未定义行为。 - 数组分配方式:用
std::make_shared<char[]>(size+1)分配能容纳整个字符串(包括终止符\0)的数组,而不是单个char元素。 - 原始指针获取:调用
shared_ptr::get()方法获取底层的char*指针,传递给memcpy或用于输出。 - 运算符[]支持:
std::shared_ptr<char[]>原生重载了[]运算符,所以你的自定义operator[]可以直接通过message[index]访问元素。 - 额外健壮性优化:新增了const版本的
operator[],支持const对象的元素访问;同时添加了越界检查,抛出标准异常避免非法内存访问。
备注:内容来源于stack exchange,提问作者weiweisss
相关产品推荐
相关产品推荐

