2013-07-12 2 views
0

Я получаю сообщение об ошибке при компиляции этого кода. Ошибка говорит '&((WidgetButton*)this)->WidgetButton::callback' cannot be used as a function. Я не знаю почему. Что я сделал не так?void ** не может использоваться как функция

Объяснение немного больше. Цель этого кода - добавить кнопку в GUI в виде ООП. callback - это функция, предоставляемая конструктору, который будет вызываться, когда кнопка активирована (нажата). Хотя сейчас он активируется только при нажатии пробела, с тем чтобы убедиться, что графический интерфейс работает с производными классами Widget.

WidgetButton.h

#pragma once 

#include "cgl.h" 
#include <GLFW/glfw3.h> 

class WidgetButton : Widget 
{ 
    public: 
     WidgetButton(GLFWwindow* window, void* callback, int sender); 

     void onUpdate(double delta); 
     void onRender(); 

    private: 
     void* callback; 
     int sender; 
}; 

WidgetButton.cpp

#pragma once 

#include "WidgetButton.h" 
#include <GLFW/glfw3.h> 

WidgetButton::WidgetButton(GLFWwindow* window, void* callback, int sender) : Widget(window) 
{ 
    this->callback = callback; 
    this->sender = sender; 
} 

void WidgetButton::onUpdate(double delta) 
{ 
    if (glfwGetKey(this->window, GLFW_KEY_SPACE)) 
     (&this->callback)(sender); //This is where the error happens 
} 

void WidgetButton::onRender() 
{ 

} 
+2

Указатели - это не то же самое, что указатели на функции, и вы должны действительно использовать что-то лучше, чем 'void *' в C++. 'void *' не следует использовать для хранения указателей на функции. – chris

+0

Ну, как я могу определить указатель на функцию? Мне кажется, что void** - это то же самое, что и указатель на функцию. –

+0

Прежде всего, вы можете встроить код с обратными окнами. Во-вторых, нормально ли иметь одну конкретную подпись обратного вызова? Если это так, нормальный указатель функции достаточно хорош: 'void (* callback) (int)' – chris

ответ

0

void * является особым типом от чего-то, что может держать функцию. Плохо попытаться поместить в него указатель функции или аналогичный. C++ имеет несколько вариантов, и самый простой, если вы едете с C или не имели дела с шаблонами слишком много это все, что нужно здесь, указатель функции:

void (*callback)(int); 

Onward, это также можно сделать то же самое с простым шаблоном:

template<typename F> 
F callback; 

Далее также можно разрешить другим типам работу с некоторыми шаблонами. Это наиболее общий способ, но он в состоянии быть настроены в соответствии с которой части вы хотите родовое:

template<typename Ret, typename... Args> 
... 
Ret (*callback)(Args...); 

Наконец, C++ предоставляет std::function, который можно использовать и здесь, но это действительно наиболее подходит для более сложных цели с большими накладными расходами:

std::function<void(int)> callback; 
+0

Когда я делаю это и делаю 'WidgetButton * button = new WidgetButton (window, callback, 0)' (обратный вызов является функцией void с 1 целым числом в качестве параметров), в нем говорится: 'no matching function для вызова 'WidgetButton :: WidgetButton (GLFWwindow * &, <неразрешенный перегруженный тип функции>, int) ''. Что случилось? –

+0

@ MonetR.Adams. Прежде всего, я рекомендую не использовать указатели и 'new', когда это возможно:' Кнопка WidgetButton (окно, обратный вызов, 0); '. Во-вторых, похоже, что вы пытаетесь передать перегруженную функцию. Если вы должны перейти в перегруженную функцию, вы должны применить ее к правильному типу (в основном к тому же типу, который используется в вызываемой функции). 'static_cast (обратный вызов)' должен работать для этого. – chris

+0

Функция «обратный вызов» находится внутри класса и не перегружена. Когда я передал его с помощью 'static_cast (callback), он просто говорит' invalid static_cast from type '<неразрешенный перегруженный тип функции>', чтобы ввести 'void (*) (int)' '. –

Смежные вопросы