首页 > 解决方案 > 如何将所有权从共享指针向量转移到另一个?

问题描述

我试图了解 C++ 中传递数据的最佳方式是什么。在下面的示例中,我试图将数据(Shader)的所有权传递给一个类(ShaderProgram)。

我可以使用原始指针来做到这一点,但这增加了管理它的生命周期的需要,而我不想这样做。不幸的是,我在read access violation尝试移动共享指针的方法中遇到了问题。

std::shared_ptr<ShaderProgram> modelShaders; // this is inside another class, but I guess it's not too important

int main() {
    std::shared_ptr<Shader> vert = std::make_shared<Shader>(Shader::VERTEX, std::string("res/shaders/model/basic.vert"));
    std::shared_ptr<Shader> frag = std::make_shared<Shader>(Shader::FRAGMENT, std::string("res/shaders/model/basic.frag"));

    std::vector<std::shared_ptr<Shader>> shaders;

    shaders.push_back(std::move(vert));
    shaders.push_back(std::move(frag));

    modelShaders->compileShaders( shaders );
}
    // std::vector<std::shared_ptr<Shader>> m_shaders; definition inside the class

void ShaderProgram::compileShaders(std::vector<std::shared_ptr<Shader>> &shaders)
{
    GLuint program = glCreateProgram();

    for (auto shaderIter = shaders.begin(); shaderIter != shaders.end(); shaderIter++)
    {
        std::shared_ptr shader = *shaderIter;

        GLuint shaderID = compileShader(shader);

        GL(glAttachShader(program, shaderID));

        shader->setID(shaderID);

        m_shaders.push_back(std::move(shader)); // here I get a read access violation
    }

我的目的是避免在不需要它的情况下创建/销毁类。我不希望 Shader 实例被破坏或复制。

PS:如果有人能推荐一些关于传递数据主题的文章等,那就太好了!

编辑

class ShaderProgram
{
private:
    std::vector<std::shared_ptr<Shader>> m_shaders;
public:
    ShaderProgram()
        : m_id(0) {};
    ~ShaderProgram() {
        std::cout << "[ShaderProgram] destroyed" << std::endl;
    };

    ...

    GLuint compileShader(const std::shared_ptr<Shader>& shader);
    void compileShaders(const std::vector<std::shared_ptr<Shader>> &shaders);

   ...
GLuint ShaderProgram::compileShader(const std::shared_ptr<Shader> &shader) {

    GLuint id = 0;
    std::string src = shader->getSource();

    const char* cSrc = src.c_str();

    GL((id = glCreateShader(shader->getGLType())));
    GL(glShaderSource(id, 1, &cSrc, NULL));
    GL(glCompileShader(id));

    if (GetStatus(id, Status::SHADER, GL_COMPILE_STATUS, shader->getName(), "COMPILATION FAILURE") != GL_TRUE)
    {
        return 0;
    }

    return id;
}

标签: c++shared-ptrsmart-pointers

解决方案


该问题与std::vector<std::shared_ptr<Shader>> m_shaders;未在构造函数中初始化有关。我承受着压力,这是由 自动处理的<vector>,但事实并非如此。通过添加以下代码,一切都按预期工作:

    ShaderProgram() : m_shaders(std::vector<std::shared_ptr<Shader>>()) {};

推荐阅读