gpt4 book ai didi

c++ - 通过参数传递成员函数指针并存储它们

转载 作者:行者123 更新时间:2023-11-28 01:08:40 25 4
gpt4 key购买 nike

我正在尝试通过我的一个小项目来解决 OOP。我正在尝试创建一个简单的 Menu 类(基于终端)来构建、显示和执行菜单。并且这个菜单应该执行来自第二类 Calendar 的功能,这是“主”程序。

我尝试实现的接口(interface)是:

int main()
{
Menu menu;
menu.add("Exit program", &Calendar::exit);
menu.show();
menu.execute(menu.EXIT); // or just 0
}

应该是这样的:

CALENDAR MENU

0 Exit program

我想要实现的是 add() 方法应该向 map 添加一个函数指针。这就是我的问题开始的地方。目前,我的 execute() 方法中有一个带有函数指针的硬编码数组。现在我想动态添加一个具有适当功能的菜单项。

class Menu {
// declaration of function-pointer thingy
typedef void (Calendar::*CalendarPtr)();

// will hold the string in the add()-method
std::vector<std::string> options_strings;
// will hold the integer associated to the appropriate function
std::map<int, CalendarPtr> options_map;
public:
// possible options
enum OPTIONS {EXIT};
// shows the menu on-screen
void show();
// should add string to vector, function-pointer to map
void add(std::string, CalendarPtr);
// should execute appropriate function (based on option passed)
void execute(OPTIONS option);
};

// ...

void Menu::add(std::string option, CalendarPtr) // what doesn't work obviously
{
// adding string to vector
options_strings.push_back(option);

// Just binding the latest entry of the string to the function-pointer
int index = options_strings.size();

// TRYING to add function-pointer to map
options_map.insert(std::pair<int, CalendarPtr>(index, CalendarPtr));
}

Menu::execute(OPTIONS option) // enum declared as public in class
{
int option = EXIT; // or 0
CalendarPtr cptr[] = {&Calendar::exit};
Calendar* cal;
if (option >= 0 && option < static_cast<int>(options_strings.size()))
(cal->*cptr[option])();
}

插入行目前给出:

../src/Menu.cpp:24: error: expected primary-expression before ';' token

这意味着我对函数指针的使用是不正确的,但是正确的方法是什么?我将如何声明所需的 add() 方法(以及哪些参数),如何在映射中插入函数指针以及如何使用我的 execute() 方法在映射中调用所需的项目?

如果有什么不清楚的地方,请说出来,我会尽力解释得更好/不同:)

提前致谢!

编辑 1:

我变了

void Menu::add(std::string option, CalendarPtr)
// ...
options_map.insert(std::pair<int, CalendarPtr>(index, CalendarPtr));

void Menu::add(std::string option, CalendarPtr cptr)
// ...
options_map.insert(std::pair<int, CalendarPtr>(index, cptr));

但是如何在插入的(比如索引 0)位置“调用”函数? options_map0;不工作...

编辑 2:

它插入了索引为 1 的函数指针;)问题解决了!

使用此方法时出现错误:

void Menu::execute(OPTIONS option)
{
Calendar c;
Calendar* calendar = &c;
CalendarPtr cptr = options_map.at(0);
(*calendar.*cptr)();
}

terminate called after throwing an instance of 'std::out_of_range' what(): map::at

所以我断定插入失败了,为什么会这样?

最佳答案

除此之外,您的添加函数应为:

void Menu::add(std::string option, CalendarPtr ptr) // what doesn't work obviously
{
// adding string to vector
options_strings.push_back(option);

// Just binding the latest entry of the string to the function-pointer
int index = options_strings.size();

// TRYING to add function-pointer to map
options_map.insert(std::pair<int, CalendarPtr>(index, ptr));
}

我建议为此实现一个委托(delegate)(例如 The Impossibly Fast C++ Delegates )。通过成员函数指针的函数调用非常慢,委托(delegate)版本会更优雅,而且速度非常快。

更新

首先:您实际上不必使用options_strings,您知道吗?你可以只使用

std::map<std::string, CalendarPtr> options_map; 

将字符串映射到成员函数指针。

更新 2:

所以一旦你恢复了你的CalendarPtr,你就可以这样调用它:

void CallIndex(Calendar* calendar, int index) {
CalendarPtr pfunc = options_map[index].second;
(*calendar).*pfunc();
}

但您可能想要 avoid syntax errors when calling a member function using a pointer-to-member-function .

关于c++ - 通过参数传递成员函数指针并存储它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4783132/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com