lundi 30 novembre 2015

Function Pointers in C++ Class Files

I've been trying to work with function pointers for quite a bit now, and to no avail. I've been working with a few friends to create a C++ 11 library to make creating ASCII games easier, and I've personally been working on creating a menu class. The beef of the class is complete, but one issue - I can't get the buttons to call functions. I always get the error:

terminate called after throwing an instance of 'std::bad_function_call'
what():  bad_function_call

This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.

Obviously the error lies somewhere in the pointers, but I can't solve it for the life of me. Thanks for the help in advance.

Menu.h

#ifndef MENU_H
#define MENU_H

using namespace std;

#include <functional>
#include <string>
#include <map>

class Menu {
    public:
        int numberOfOptions;
        map<int, string> options;
        int currentSelection;
        string title;

        Menu();
        Menu(int initialNumberOfOptions, map<int, string> initialOptions, int initialSelection);
        void display();
        void waitForInput();
        void attachOptionAction(int option, void (*function)());

    private:
        map<int, void (*std::function<void()>)> optionActions;

        void executeOptionAction(int option);
};

#endif

Menu.cpp

#include "Menu.h"
#include <windows.h>
#include <iostream>
#include <conio.h>

Menu::Menu(int initialNumberOfOptions, map<int, string> initialOptions, int initialSelection) {
    title = "";
    numberOfOptions = initialNumberOfOptions;
    options = initialOptions;
    currentSelection = initialSelection;
}

void Menu::display() {
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), {0, 0});
    for(int i = 0; i < 10; i++) {
        cout << "          " << endl;
    }

    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), {0, 0});
    if(title != "") {
        cout << title << endl << endl;  
    }

    for(int i = 0; i < numberOfOptions; i++) {
        if(i == currentSelection - 1) {
            cout << "[ " << options[i] << " ]" << endl;
        } else {
            cout << options[i] << endl;
        }
    }
    waitForInput();
}

void Menu::waitForInput() {
    char input;
    while(!kbhit());
        input = getch();
    if(input == 72 && currentSelection > 1) {
        currentSelection--;
    } else if (input == 80 && currentSelection < numberOfOptions) {
        currentSelection++;
    } else if (input == 13) {
        if(currentSelection == 1) {
            executeOptionAction(1);
        }
        return;
    }

    display();
}

void Menu::attachOptionAction(int option, std::function<void()> function) {
    optionActions[option] = function;
}

void Menu::executeOptionAction(int option) {
    (optionActions[option])();
}

test.cpp

#include "Menu.h"
#include <unistd.h>
#include <iostream>
#include <iomanip>
#include <map>

void test() {
    cout << "Hello, World!";
}

int main() {
    map<int, string> options;
    options[0] = "Play";
    options[1] = "Help";
    options[2] = "Quit";
    Menu menu(3, options, 1);
    menu.title = "ASCII Game Library 2015";
    menu.display();

    void (*actionPointer)() = NULL;
    menu.attachOptionAction(1, (*actionPointer));

    return 0;
}

Aucun commentaire:

Enregistrer un commentaire