将成员函数指针设置为空闲函数指针

Posted

技术标签:

【中文标题】将成员函数指针设置为空闲函数指针【英文标题】:Set member function pointer to free function pointer 【发布时间】:2020-08-05 15:52:52 【问题描述】:

我正在开发一个用 c++ 编码并用 ctypes 包装的简单引擎。我正在研究窗口类,我想让引擎用户能够设置绘制和更新功能。我有以下代码:

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();
    void (window::*draw)();

    void setDrawFunction(void (window::*)());
    void setUpdateFunction(int*);
;

window.cpp

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

#include "window.h"

void default_draw() 
    glClear(GL_COLOR_BUFFER_BIT);


void default_update() 
    


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;
    

    setDrawFunction((void)(window::*)()default_draw);


void window::close() 
    glfwDestroyWindow(this->wnd);


void window::update() 
    default_update();


void window::setDrawFunction(void (window::*fnptr)()) 
    draw = fnptr;

这不起作用。我是否遗漏了一些明显的东西,或者不可能以这种方式完成。如果是这样,我有什么办法可以做到这一点?我所需要的只是能够过载功能,所以我可以在 python 中使用 ctypes 来实现。

我得到的错误: 109 调用前的表达式必须有函数(指针)类型 29 表达式预期 18 应为“)”

【问题讨论】:

default_draw 不是成员函数。您必须添加显式 C 转换 (void)(window::*)() 才能调用 setDrawFunction compile 的事实很好地表明您没有正确使用它。你需要给它一个window 成员函数。 问题是,我仍然需要以某种方式覆盖类之外的绘制函数。 您可能有兴趣了解std::function 对不起,标题不是实际的。现在已更正,问题是一样的。我会立即发布它的更正版本和错误 如果您仍然想要一个面向对象的解决方案同时与 C(和 ctypes)兼容,请考虑使用 void(member*) 函数而不是 void()。然后draw函数可以用draw(this);调用draw函数。 【参考方案1】:

使用window的成员函数指针作为成员变量是不合适的。

我可以考虑以下选项来解决这个问题。

选项 1

draw 设为非成员函数指针。

void (*draw)();

void setDrawFunction(void (*func)());

选项 2

draw 设为std::function

std::function<void()> draw;

void setDrawFunction(std::function<void()> func);

选项 3

使用单独的类/接口进行绘图。

std::unique_ptr<DrawingAgent> draw;

void setDrawingAgent(std::unique_ptr<DrawingAgent> agent);

在哪里

class DrawingAgent

   public:
      virtual void draw(window*); // Draw in given window.
;

在上述选项中,我建议使用选项 3。它将应用程序的 窗口 方面与 绘图 功能清晰地分开。

【讨论】:

实际上我使用了@FrancoisAndrieux 推荐给我的选项 1,但感谢您的回复

以上是关于将成员函数指针设置为空闲函数指针的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 C++ lambda 将成员函数指针转换为普通函数指针以用作回调

C++:将派生指针转换为 void 指针,然后转换为抽象指针,并访问成员函数

C++函数指针与成员函数指针

c++怎样将指向【成员函数】的指针强转成指向【普通函数】的指针

指向虚拟成员函数的指针是不是具有可比性?

C++ 指向成员函数指针问题