Как перенести право собственности с одного вектора на общие указатели на другой? - PullRequest
0 голосов
/ 16 июня 2019

Я пытаюсь понять, как лучше всего в 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
    }

Моя цель - избегать создания / уничтожения классов без необходимости. Я не хочу, чтобы экземпляры шейдера уничтожались или копировались.

PS: Если кто-то может порекомендовать несколько статей и т. Д. На тему передачи данных, это было бы здорово!

EDIT

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;
}

1 Ответ

0 голосов
/ 17 июня 2019

Проблема связана с тем, что std::vector<std::shared_ptr<Shader>> m_shaders; не инициализируется в конструкторе. Я был под давлением, это автоматически позаботилось о <vector>, но это было не так. Добавив следующий код, все заработало как положено:

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