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

使用智能指针实现自定义字符串类时的运算符[]及类型转换错误解决求助

使用智能指针实现自定义字符串类时的运算符[]及类型转换错误解决求助

看起来你在实现自定义字符串类的时候踩了std::shared_ptr的两个常见坑,我来帮你一步步拆解并解决这些问题:

先分析错误原因

  1. 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的数组——这完全不符合你存储字符串的需求!

  2. no operator "[]" matches these operands
    std::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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.23 08:19:12