C++中不带括号的方法
Method without parenthises in C++
所以我目前正在编写一个 C++ OpenGL 程序,我对这门语言还很陌生。
没有括号的方法叫什么?
我的代码块:
Program.cpp:
Input input;
glfwSetKeyCallback(window, input.HandleInput); //On this line input.HandleInput is the question at hand
Input.h
class Input
{
public:
void HandleInput(GLFWwindow* window, int key, int scancode, int action, int mods);
private:
};
Input.cpp
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "Input.h"
void Input::HandleInput(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_F && action == GLFW_PRESS)
{
std::cout << key << " pressed.";
}
}
此外,如果有人能告诉我如何正确执行 input.HandleInput 方法,我将不胜感激。
方法glfwSetKeyCallback
接受一个函数指针作为它的参数。函数指针是 C 和 C++ 功能中相对重要的部分,并且是实现回调的常用习惯用法,如本例所示。
GLFW 将如何处理传递给它的函数是它具有系统事件的内部轮询功能(您使用 glfwPollEvents();
调用),在遇到系统事件时,会将其转换为系统事件- 不可知论形式,可以使用您提供的回调进行解释。
然而,GLFW 是用 C 编写的,无法处理 C++ 原生的更复杂、更高级的函数指针或函子,因此当我们将函数指针传递给 GLFW 时,我们需要将其简化为更简单的形式。对象的成员函数不会削减它。这是因为像这样的方法:
class Input
{
public:
void HandleInput(GLFWwindow* window, int key, int scancode, int action, int mods);
private:
};
秘密地,根据编译器,实际上是这样的:
void Input__HandleInput(Input * ptr, GLFWwindow* window, int key, int scancode, int action, int mods);
并且由于此签名与 GLFW 对回调的期望不匹配,因此不会接受它。
如果您打算使用 class 函数作为此函数的回调,则需要将其设为静态。
struct Input {//'class' is fine, but 'struct' reduces boilerplate
static void HandleInput(GLFWwindow* window, int key, int scancode, int action, int mods);
};
int main() {
glfwInit();
GLFWWindow* window = glfwCreateWindow(/*...*/);
glfwSetKeyCallback(window, Input::HandleInput);
}
但是,这对您来说可能是个问题。毕竟,您可能专门为此回调功能编写了一个 class 来提供对您所需行为的一些封装。被迫恢复使用静态函数或全局函数会破坏此目的。
相反,您需要使用 GLFW 集成的用户指针功能。
struct InputHandler {
static void HandleKey(GLFWwindow* window, int key, int scancode, int action, int mods) {
//Perfectly legal: we fully intend to only permit the User Pointer to be of type 'InputHandler*'
InputHandler & handler = *reinterpret_cast<InputHandler*>(glfwGetWindowUserPointer(window));
handler.handleKeyImpl(window, key, scancode, action, mods);
}
void handleKeyImpl(GLFWwindow* window, int key, int scancode, int action, int mods) {
/*...*/
}
};
int main() {
glfwInit();
InputHandler input;
GLFWWindow* window = glfwCreateWindow(/*...*/);
glfwSetWindowUserPointer(window, &input);
glfwSetKeyCallback(window, Input::HandleInput);
}
所以我目前正在编写一个 C++ OpenGL 程序,我对这门语言还很陌生。 没有括号的方法叫什么?
我的代码块:
Program.cpp:
Input input;
glfwSetKeyCallback(window, input.HandleInput); //On this line input.HandleInput is the question at hand
Input.h
class Input
{
public:
void HandleInput(GLFWwindow* window, int key, int scancode, int action, int mods);
private:
};
Input.cpp
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include <iostream>
#include "Input.h"
void Input::HandleInput(GLFWwindow* window, int key, int scancode, int action, int mods)
{
if (key == GLFW_KEY_F && action == GLFW_PRESS)
{
std::cout << key << " pressed.";
}
}
此外,如果有人能告诉我如何正确执行 input.HandleInput 方法,我将不胜感激。
方法glfwSetKeyCallback
接受一个函数指针作为它的参数。函数指针是 C 和 C++ 功能中相对重要的部分,并且是实现回调的常用习惯用法,如本例所示。
GLFW 将如何处理传递给它的函数是它具有系统事件的内部轮询功能(您使用 glfwPollEvents();
调用),在遇到系统事件时,会将其转换为系统事件- 不可知论形式,可以使用您提供的回调进行解释。
然而,GLFW 是用 C 编写的,无法处理 C++ 原生的更复杂、更高级的函数指针或函子,因此当我们将函数指针传递给 GLFW 时,我们需要将其简化为更简单的形式。对象的成员函数不会削减它。这是因为像这样的方法:
class Input
{
public:
void HandleInput(GLFWwindow* window, int key, int scancode, int action, int mods);
private:
};
秘密地,根据编译器,实际上是这样的:
void Input__HandleInput(Input * ptr, GLFWwindow* window, int key, int scancode, int action, int mods);
并且由于此签名与 GLFW 对回调的期望不匹配,因此不会接受它。
如果您打算使用 class 函数作为此函数的回调,则需要将其设为静态。
struct Input {//'class' is fine, but 'struct' reduces boilerplate
static void HandleInput(GLFWwindow* window, int key, int scancode, int action, int mods);
};
int main() {
glfwInit();
GLFWWindow* window = glfwCreateWindow(/*...*/);
glfwSetKeyCallback(window, Input::HandleInput);
}
但是,这对您来说可能是个问题。毕竟,您可能专门为此回调功能编写了一个 class 来提供对您所需行为的一些封装。被迫恢复使用静态函数或全局函数会破坏此目的。
相反,您需要使用 GLFW 集成的用户指针功能。
struct InputHandler {
static void HandleKey(GLFWwindow* window, int key, int scancode, int action, int mods) {
//Perfectly legal: we fully intend to only permit the User Pointer to be of type 'InputHandler*'
InputHandler & handler = *reinterpret_cast<InputHandler*>(glfwGetWindowUserPointer(window));
handler.handleKeyImpl(window, key, scancode, action, mods);
}
void handleKeyImpl(GLFWwindow* window, int key, int scancode, int action, int mods) {
/*...*/
}
};
int main() {
glfwInit();
InputHandler input;
GLFWWindow* window = glfwCreateWindow(/*...*/);
glfwSetWindowUserPointer(window, &input);
glfwSetKeyCallback(window, Input::HandleInput);
}