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

如何像普通指针一样对唯一指针进行索引与写入?附代码示例

用std::unique_ptr替代原始指针操作OpenGL映射缓冲区

我来帮你搞定这个问题——要让std::unique_ptr像普通指针那样支持索引和写入,同时适配OpenGL映射缓冲区的特殊内存管理,核心是自定义删除器,因为这块内存不是用new分配的,不能让unique_ptr默认调用delete。下面是具体的实现步骤和代码示例:

1. 定义带自定义删除器的unique_ptr类型

首先我们封装一个适合的unique_ptr类型,复用起来更方便:

#include <memory>
// 你的sphere结构体定义
struct alignas(16) sphere { glm::vec4 center; glm::vec4 color; float radius; };

// 定义带自定义删除器的unique_ptr,删除器负责解除OpenGL缓冲区映射
using UniqueSpherePtr = std::unique_ptr<sphere, void(*)(sphere*)>;

2. 创建自定义删除器

我们需要让unique_ptr在生命周期结束时自动调用glUnmapNamedBuffer释放映射内存,而非默认的delete。用lambda实现这个删除器:

// 捕获缓冲区对象m_sphere_buffer,确保删除器能正确解除对应缓冲区的映射
auto sphere_deleter = [m_sphere_buffer](sphere* ptr) {
    if (ptr != nullptr) {
        glUnmapNamedBuffer(m_sphere_buffer);
    }
};

3. 用unique_ptr接管映射的内存

替换你原来的原始指针赋值逻辑,用UniqueSpherePtr接管glMapNamedBufferRange返回的指针:

// 替换原来的sphere* m_sphere_ptr;
UniqueSpherePtr m_sphere_ptr(
    static_cast<sphere*>(glMapNamedBufferRange(
        m_sphere_buffer, 
        0, 
        m_spheres.size() * sizeof(sphere), 
        GL_MAP_WRITE_BIT
    )),
    sphere_deleter
);

4. 索引和写入操作和普通指针完全一致

std::unique_ptr已经重载了operator[],所以你原来的循环代码不需要任何修改,直接像普通指针一样使用即可:

auto sphere_x_offset { 5.0f };
for (int index{ 0 }; index < m_spheres.size(); ++index) {
    float sphere_x { static_cast<float>(index) / m_spheres.size()};
    // 直接用[]索引,和原始指针用法完全一样
    m_sphere_ptr[index].center = glm::vec4{ sphere_x + sphere_x_offset, 0.0f, 0.0f, 1.0f };
    // 其他字段的写入也同理
    m_sphere_ptr[index].color = glm::vec4{ 1.0f, 0.5f, 0.2f, 1.0f };
    m_sphere_ptr[index].radius = 1.0f;
}

关键注意事项

  • 检查映射是否成功:glMapNamedBufferRange可能返回nullptr,建议增加错误检查:
    if (!m_sphere_ptr) {
        GLenum err = glGetError();
        // 这里添加错误处理逻辑,比如打印错误信息
    }
    
  • 不要手动调用glUnmapNamedBuffer:unique_ptr会在自身销毁时自动调用删除器完成解除映射,手动调用会导致重复操作,引发OpenGL错误。
  • 确保捕获的缓冲区有效:如果用lambda作为删除器,要保证m_sphere_buffer在unique_ptr的整个生命周期内都是有效的(比如缓冲区对象没有被提前销毁)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 03:36:29