Как инициализировать указатель члена на бесплатную функцию? - PullRequest
0 голосов
/ 05 августа 2020

Я пытаюсь создать класс с указателем, который можно изменить вне класса. Независимо от того, что я делаю, я либо получаю синтаксическую ошибку, либо указатель просто не инициализируется У меня следующий код:

window.h

#pragma once
#include <GL/glew.h>
#include <GLFW/glfw3.h>
class window
{
public:
    GLFWwindow* wnd;

    window(int width, int height, const char* title);
    void close();

    void (*update)(window*);
    void (*draw)(window*);

    void run();

    void setDrawFunction(void (*fnptr)(window*));
    void setUpdateFunction(void (*fnptr)(window*));
};

window. cpp

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include "window.h"

void default_draw(window* wnd) {
    glClear(GL_COLOR_BUFFER_BIT);
}

void default_update(window* wnd) {
    
}

window::window(int width, int height, const char* title)
{
    glfwWindowHint(GLFW_SAMPLES, 4);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
    glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    glfwWindowHint(GLFW_OPENGL_COMPAT_PROFILE, GL_TRUE);
    glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

    wnd = glfwCreateWindow(width, height, title, NULL, NULL);

    if (wnd == NULL) { glfwTerminate(); return; }

    glfwMakeContextCurrent(wnd);

    if (glewInit() != GLEW_OK) {
        glfwTerminate();
        return;
    }

    //This does not work
    draw = default_draw;
    update = default_update;
}

void window::close() {
    glfwDestroyWindow(wnd);
}

void window::setDrawFunction(void(*fnptr)(window*)) {
    // And so does this
    draw = fnptr;
}

void window::setUpdateFunction(void(*fnptr)(window*)) {
    update = fnptr;
}

void window::run() {
    while (glfwWindowShouldClose(wnd) == 0)
    {
        glClear(GL_COLOR_BUFFER_BIT);

        //update(this);
        draw(this); // This will cause attempt to access 0x0000000000000

        glfwSwapBuffers(wnd);
        glfwPollEvents();
    }

    close();
}

Я много чего перепробовал, но ничего не вышло. Я делаю что-то неправильно? Мне нужно использовать указатели, потому что эта вещь выше является частью простого движка, обернутого позже в python с использованием ctypes.

EDIT: предыдущая версия могла быть немного неясной. У меня проблемы с функцией рисования. Я пытаюсь объявить указатель на бесплатную функцию, а затем установить его в конструкторе и функции. Проблема в том, что переменная явно не установлена ​​должным образом.

1 Ответ

0 голосов
/ 06 августа 2020

Вместо использования необработанных указателей функций используйте std :: function:

window.h:

#include <functional>
// [...]

class window {
// [...]

  public:
     std::function<void(window *)> update;
     std::function<void(window *)> draw;
// [...]
}

window. cpp:

void window::setDrawFunction(std::function<void(window *)> fnptr) {
    draw = fnptr;
}

void window::setUpdateFunction(std::function<void(window *)> fnptr) {
    update = fnptr;
}

Чтобы узнать больше, отметьте https://en.cppreference.com/w/cpp/utility/functional/function.

Вы можете инициализировать эти функции в своем конструкторе класса, используя список инициализации следующим образом:

window::window(int width, int height, const char* title)
: update(default_update), draw(default_draw)
{
// [...]
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...