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

使用std::shared_ptr<char[]>时简化std::copy调用的方法咨询

问题描述

把C++代码里的char*替换成std::shared_ptr<char[]>后,调用std::copy时得反复写.get(),原本简洁的写法:

copy(src.m_name, src.m_name + size, dst.m_name);

变成了冗余的:

copy(src.m_name.get(), src.m_name.get() + size, dst.m_name.get());

想找更简洁的写法,不用重复输入.get()。


相关代码示例
#include <iostream>
#include <memory>
#include <algorithm>
#include <cstring>

struct Data
{
    std::shared_ptr<char[]> m_name = nullptr;  // 原代码为char* m_name = nullptr;

    Data() = default;

    Data(const char* name)
    {
        using std::copy;

        int size = strlen(name) + 1;
        m_name = std::make_shared<char[]>(size); // 原代码为m_name = new char[size];
        copy(name, name + size, m_name.get());
    }

    void print()
    {
        using std::cout, std::endl;

        if (!m_name)
            return;
        int size = strlen(m_name.get());
        for(int i = 0; i < size; ++i)
            cout << m_name[i];
        cout << endl;
    }
};

void shallow_copy(Data& dst, Data& src)
{
    dst.m_name = src.m_name;
}

void deep_copy(Data& dst, Data& src)
{
    using std::copy;

    int size = strlen(src.m_name.get())+1;
    dst.m_name = std::make_shared<char[]>(size); // 原代码为dst.m_name = new char[size];
    copy(src.m_name.get(), src.m_name.get() + size, dst.m_name.get());
}

int main()
{
    using std::cout, std::endl;

    cout << "starting..." << endl;

    auto data1 = new Data{"abc"};
    data1->print();

    auto data2 = new Data();
    data2->print();

    deep_copy(*data2, *data1);

    data2->print();

    delete data1;
    delete data2;
}

注:修正了原代码中make_unique与shared_ptr不匹配的错误,补充了必要头文件和内存释放逻辑。


解决方案

1. 提前缓存原始指针

在调用std::copy前,把shared_ptr的原始指针存入临时变量,避免重复调用.get():

void deep_copy(Data& dst, Data& src)
{
    using std::copy;
    char* src_ptr = src.m_name.get();
    int size = strlen(src_ptr) + 1;
    
    dst.m_name = std::make_shared<char[]>(size);
    char* dst_ptr = dst.m_name.get();
    
    copy(src_ptr, src_ptr + size, dst_ptr);
}

2. 用std::span简化迭代(C++20及以上)

利用std::span包装原始指针,直接使用迭代器接口,仅需一次.get()调用:

#include <span>

void deep_copy(Data& dst, Data& src)
{
    using std::copy;
    char* src_ptr = src.m_name.get();
    int size = strlen(src_ptr) + 1;
    
    dst.m_name = std::make_shared<char[]>(size);
    std::span src_span(src_ptr, size);
    std::span dst_span(dst.m_name.get(), size);
    
    copy(src_span.begin(), src_span.end(), dst_span.begin());
}

3. 改用std::string(推荐)

如果业务场景允许,直接用std::string替代std::shared_ptr<char[]>是最优解——它自带深拷贝、迭代器支持,完全不需要手动管理内存和.get()调用:

#include <iostream>
#include <string>

struct Data
{
    std::string m_name;

    Data() = default;
    explicit Data(const char* name) : m_name(name) {}

    void print()
    {
        using std::cout, std::endl;
        cout << m_name << endl;
    }
};

void deep_copy(Data& dst, Data& src)
{
    dst.m_name = src.m_name; // std::string默认就是深拷贝
}

int main()
{
    using std::cout, std::endl;

    cout << "starting..." << endl;

    Data data1{"abc"};
    data1.print();

    Data data2;
    data2.print();

    deep_copy(data2, data1);

    data2.print();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 12:05:20