基本思想
在Menu对象里存储各个选项对应的函数指针。
功能简介
使用了可变参数函数进行Menu对象的构造。
setPrmt()可设置选项选择时的文本提示。
使用成员函数choose()包揽了菜单的选项选择过程,使多个菜单不再需大量重复的代码实现。
testAll()可将包含的函数全部执行,主要是测试时用到。
注意事项
目前仅支持 void返回类型且无参的函数 被包含在Menu对象中。
至于多级菜单的嵌套,在菜单对象的选项调用的函数中再新建菜单对象即可。
目前默认输入i则调用第i个函数(从1开始),然后执行完该函数后可继续在该级菜单继续选择,输入0或其他字符则退出此次选择。
Menu.h
#pragma once
#include<iostream>
#include<sstream>
#include<vector>
using namespace std;
class Menu
{
vector<void (*)()> funcLst;
string promote;
public:
template<typename... T>
Menu(T... args) {
for (auto x : { args... }) {
funcLst.push_back(x);
}
}
void setPrmt(string prmt);// 设置提示
void testAll();// 调用所有包含的函数
void choose();
static inline void psCls()
{
system("pause");
system("cls");
}
};
Menu.cpp
#include "Menu.h"
void Menu::setPrmt(string prmt)
{
promote = prmt;
return;
}
void Menu::testAll()
{
for (int i = 0; i < funcLst.size(); ++i)
{
funcLst[i]();
}
return;
}
void Menu::choose()
{
Bg:
cout << endl << promote;
string s;
stringstream ss;
int i=0;
while (s.size() == 0) {// 防范cin等留在缓存区中的换行符
getline(cin, s);
//cout << "getline\n"; // 示踪,查看跳过换行符情况
}
ss << s;
ss >> i;
if (i == 0 || i - 1 >= funcLst.size()) {
return;
}
else{
funcLst[i-1]();
//psCls(); 暂停以及清屏
goto Bg;
}
}
使用示例
#include <iostream>
#include"Menu.h"
void func1()
{
cout << "func1\n";
}
void func2()
{
cout << "func2\n";
}
void func3()
{
cout << "func3\n";
}
void func4()
{
Menu m(func3);
m.setPrmt("1:func3 其他:返回\n");
m.choose();
}
int main()
{
Menu a(func1, func2,func4);
a.setPrmt("1:fc1 2:fc2 3:fc4 其他:退出\n");
//a.testAll();
//int b;
//cin >> b; // 试验对换行符的跳过效果
a.choose();
return 0;
}