Использование friend funtions в С++

303
03 апреля 2018, 00:23

Здравствуйте, изучаю вот OpenGL, и наткнулся на совсем мне непонятную проблему, вот код:

Window.h

// ...
#include "../Input/EventListener.h"
namespace Graphic 
{
    static Utils::Logger logger;
    class Window
    {
    public:
        // ...
    private:
        bool init();
        // ...
    private:
        const char* _title;
        GLint _width;
        GLint _height;
        GLFWwindow* _window;
    };
    // Если я ставлю в область класса и меняю static на friend, то перестает работать
     static void resize_callback(GLFWwindow* window, GLint width, GLint height);
}

Window.cpp

#include "Window.h"
namespace Graphic 
{
    // ...
    bool Window::init()
    {
        // ...
        _window = glfwCreateWindow(_width, _height, _title, NULL, NULL);
        Input::EventListener listener(_window);
        glfwMakeContextCurrent(_window);
        // Эта строка кода не работает, если я меняю static на friend и вношу в тело класса
        glfwSetWindowSizeCallback(_window, resize_callback);
        // Вот эти три строки кода не работают(пробовал и без указания namespace), ошибка представлена ниже
        glfwSetKeyCallback(_window, Input::key_callback);
        glfwSetMouseButtonCallback(_window, Input::btn_callback);
        glfwSetCursorPosCallback(_window, Input::mouse_position_callback);
        // ...
     }
     void resize_callback(GLFWwindow * window, GLint width, GLint height)
     {
         logger.trace("Size of window was changed on [" + std::to_string(width) + "-" + std::to_string(height) + "]");
         glViewport(0, 0, width, height);
     }
 }

EventListener.h

 #include "../Graphics/Window.h"
 #include "../Utils/Logger.h"
 #define MAX_COUNT_KEYS 1000
 #define MAX_COUNT_BTNS 32
 namespace Input
 {
    static Utils::Logger logger;
    class EventListener
    {
    public:
         EventListener(GLFWwindow* window);
         // ...
    private:
        // Если я вынесу эти методы из тела класса то будет работать, но придется делать поля класса публичными
        friend void key_callback(GLFWwindow* window, int key, int scancade, int action, int mode);
        friend void btn_callbak(GLFWwindow* window, int btn, int action, int mode);
        friend void mouse_position_callback(GLFWwindow* window, double xPos, double yPos);
    private:
        bool _keys[MAX_COUNT_KEYS];
        bool _btns[MAX_COUNT_BTNS];
        double _xPosMouse;
        double _yPosMouse;
    };
}

EventListener.cpp

#include "EventListener.h"
namespace Input 
{
     // ...
    // Также пробовал без явного указания namespace у методов
    void Input::key_callback(GLFWwindow * window, int key, int scancade, int action, int mode)
    {
        EventListener* listener = static_cast<EventListener*>(glfwGetWindowUserPointer(window));
        if (listener->_keys[key] = (action != GLFW_RELEASE))
        {
            logger.trace("Key " + std::to_string(key) + " was predssed.");
        }
    }
    void Input::btn_callbak(GLFWwindow * window, int btn, int action, int mode)
    {
        EventListener* listener = static_cast<EventListener*>(glfwGetWindowUserPointer(window));
        if (listener->_btns[btn] = (action != GLFW_RELEASE))
        {
            logger.trace("Button " + std::to_string(btn) + " was predssed.");
        }
    }
    void Input::mouse_position_callback(GLFWwindow * window, double xPos, double yPos)
    {
        EventListener* listener = static_cast<EventListener*>(glfwGetWindowUserPointer(window));
        listener->_xPosMouse = xPos;
        listener->_yPosMouse = yPos;
        logger.trace("Mouse position [X: " + std::to_string(xPos) + " - Y: " + std::to_string(yPos) + "]");
    }
    // ...
}

Ошибка

E0135   namespace "Input" не содержит члена "key_callback"  FastEngine  c:\Users\vova\Desktop\FastEngine\Graphics\Window.cpp    31  
E0135   namespace "Input" не содержит члена "btn_callback"  FastEngine  c:\Users\vova\Desktop\FastEngine\Graphics\Window.cpp    32  
E0135   namespace "Input" не содержит члена "mouse_position_callback"   FastEngine  c:\Users\vova\Desktop\src\FastEngine\Graphics\Window.cpp    33  
C2664   "GLFWkeyfun glfwSetKeyCallback(GLFWwindow *,GLFWkeyfun)": невозможно преобразовать аргумент 2 из "void (__cdecl *)(GLFWwindow *,int,int,int,int)" в "GLFWkeyfun"    FastEngine  c:\users\vova\desktop\fastengine\graphics\window.cpp    31  
C2039   btn_callback: не является членом "Input"    FastEngine  c:\users\vova\desktop\fastengine\graphics\window.cpp    32  
C2065   btn_callback: необъявленный идентификатор   FastEngine  c:\users\vova\desktop\fastengine\graphics\window.cpp    32  
C2664   "GLFWcursorposfun glfwSetCursorPosCallback(GLFWwindow *,GLFWcursorposfun)": невозможно преобразовать аргумент 2 из "void (__cdecl *)(GLFWwindow *,double,double)" в "GLFWcursorposfun"  FastEngine  c:\users\vova\desktop\fastengine\graphics\window.cpp    33  

Как раз таки где используются эти дружественные функции, вообщем я уже просто не знаю что мне делать, почти все перепробовал, очень надеюсь на чью-то помощь. Заранее спасибо

READ ALSO
Составить программу в C++ [требует правки]

Составить программу в C++ [требует правки]

Даны действительные числа х, у, zПолучить: a) max(x,y,z); b)min(x,y,z), max(x,y,z)

242
вычисление jsmath в браузере

вычисление jsmath в браузере

Доброго времени этого не пишут в учебниках хочу заставить Лису(FF) вычислять math функцию внутри браузера, а не через Windows (ADVAPI32DLL Function36)

232
Асинхронное чтение данных с сервера

Асинхронное чтение данных с сервера

Какой самый удобный способ (С++) для асинхронного чтения постоянно приходящих с сервера данных? Платформа Windows

206
проверить системное время с++

проверить системное время с++

Как проверить системное время и если оно равно например 12:46, написать в консоль?

209