C++:单向跳转到函数.任何替代方案
C++ : One way jump to functions... any alternative?
我是一名学生,正在学习 c++。去年我为我的 skul 做了一个简单的项目,现在我意识到为了使其用户友好,我从一个函数到另一个函数进行了多次调用,而不考虑堆栈和它会导致的内存泄漏。基本上,它是一个学生数据库管理系统,我已经制作了一个对应于一个屏幕的功能,即一个用于菜单的功能,一个用于添加数据,修改数据等的功能。代码很大,所以我粘贴了一小部分.只需观察我如何首先从menu((调用add1((,然后再次从add1((调用menu((...
`//***************************STUDENT DATABASE***********************************
void add1(){
system("CLS");
char ch;
int i=no;
do{
i++;
cout<<"nName : ";
cin.ignore ( std::numeric_limits<std::streamsize>::max(), 'n' );
getline (cin,s[i].name);
cout<<"nClass : ";
cin>>s[i].cl;
cout<<"nRollno : ";
cin>>s[i].rollno;
cout<<"nMarks in";
s[i].m.avg=0;
for(int j=0;j<maxsb;j++)
{
cout<<"n"<<subject[j]<<": ";
cin>>s[i].m.s[j];
s[i].m.avg+=(s[i].m.s[j]/maxsb);
}
no=i;
cout<<"nPress 'n' for next and 'b' to exit : ";
cin>>ch;
cout<<"n***********************************************************************";
}while(ch=='n');
menu(); //calling menu() again from this function...
}
//*************
void menu(){
system("CLS");
int n,flag=0;
do
{
cout<<"1.ADD DATAn2.VIEW REPORTn3.MODIFY DATAn4.DELETE DATAn5.SORT DATAn6.GO BACK TO PREVIOUS MENUn";
cout<<"PLEASE ENTER YOUR CHOICE(enter corresponding integer): ";
cin>>n;
switch(n)
{ case 2: report();break;
case 1: add1();break;
case 3: modify();break;
case 4: del();break;
case 5: sort();break;
case 6: first();
default:cout<<"PLEASE ENTER A VALID CHOICE";system("CLS");flag=1;
}
}
while(flag==1);
}
//**************
void first()
{
system("CLS");
int n,flag=0;
cout<<"tttSoftware for Teachers";
cout<<"nn1.Student Databasenn2.Play Gamenn3.Calculator";
cout<<"nnEnter your choice: ";
do{
flag=0;
cin>>n;
switch(n)
{
case 1:{ if(flag2==0)
{ setting();
flag2=1;
}
menu(); }
break;
case 2: game();
break;
// case 3: calculator();
// break;
default: cout<<"nPlz enter a valid choice nn Enter your choice again: ";flag=1;
}
}
while(flag);
}
//******************************************************************************
int main()
{
int temp;
first();
cin>>temp;
}
`
这种从一个函数跳到另一个函数然后再也不返回在我的代码中已经做过几次了,我现在意识到,杀死了堆栈。我已经用谷歌搜索了很多,我知道首先不可能单向从一个函数随机跳到另一个函数,并且将所有内容组合在一个函数中并使用 goto 从一个块跳到另一个块不是一个好主意(它实际上更糟!!所以,我的问题是,有没有更好的方法可以完成这项任务?(这里的意思是我在上面的代码中试图做的事情,即该程序的用户友好性(
谢谢
调用 menu()
或 first()
返回上一个菜单,而是使用 return
。例如,在menu()
函数中:
case 6: return;
这意味着控件将在函数调用后立即返回到调用函数。例如,当您从add1
返回到menu
时,执行将继续在请求选择的循环中。
只需将 menu(((在函数内部或外部(括在一个循环中,然后从 add1 函数正常返回。
void add1(){
…..
}while(ch=='n');
return; <--------------
}
void menu(){
while(true) <------------------
{
system("CLS");
int n,flag=0;
do
{
cout<<"1.ADD DATAn2.VIEW REPORTn3.MODIFY DATAn4.DELETE DATAn5.SORT DATAn6.GO BACK TO PREVIOUS MENUn";
cout<<"PLEASE ENTER YOUR CHOICE(enter corresponding integer): ";
cin>>n;
switch(n)
{ case 2: report();break;
case 1: add1();break;
case 3: modify();break;
case 4: del();break;
case 5: sort();break;
case 6: return; <-------------------
default:cout<<"PLEASE ENTER A VALID CHOICE";system("CLS");flag=1;
}
}
while(flag==1);
}
}
你应该让处理程序函数(即add1()
(返回到主函数,这将在循环中再次调用menu()
,直到你要求退出。
您是否曾经在马里奥等游戏机上玩过街机游戏?在这样的游戏中,我们有多级菜单(带有子菜单的菜单;每个屏幕一个菜单(。希望,这是你想要实现的。
在电脑游戏中,通常,我们使用堆栈数据结构(LIFO(实现这样的菜单(状态(。
-
将菜单屏幕(状态(包装到对象中。所有资源都在构造函数中初始化,所有清理都在析构函数中进行,因此没有泄漏。
class IState { public: virtual ~IState() {} virtual void Apply() = 0; }; class MainMenuState : public IState { public: MainMenuState() { /*Here goes resources allocation*/ } virtual ~MainMenuState() { /*Here goes resources freeing*/ } virtual void Apply() override { /*Here goes menu rendering*/ } }; class SettingsMenuState : public IState { public: SettingsMenuState() { /*Here goes resources allocation*/ } virtual ~SettingsMenuState() { /*Here goes resources freeing*/ } virtual void Apply() override { /*Here goes menu rendering*/ } };
-
将状态存储在堆栈中
std::stack<IState> states;
-
当用户必须看到新菜单时,您推送状态:
states.push(MainMenuState()); // initial menu if (userWantsToSettings) { states.push(SettingsMenuState()); // second level }
-
当用户想要返回时,您弹出状态
if (userWantsGoBack) { states.pop(); }
-
有时(对于游戏,每帧一次,对于控制台应用程序,它可以是用户按下按钮一次(您调用
Update()
来呈现最顶层的菜单:void Update() { states.top().Apply(); }
裁判:
制作主菜单系统的最佳方法是什么?
我应该如何构建我的菜单/游戏循环?
希望对您有所帮助。祝您编码愉快!=)
- 如果C++类在类方法中具有动态分配,但没有构造函数/析构函数或任何非静态成员,那么它仍然是POD类型吗
- 为什么我不能在 C++ 中的特定函数重载中调用同一函数的任何其他重载?
- C++模板函数,用于比较任何无符号整数和有符号整数
- 是否有任何建议来统一函数类型限定符并简化可恶的函数类型?
- C++中是否有任何函数等同于python中字典的get函数?
- 用于检查值是否为其任何参数的帮助程序函数
- C++ - 声明指向返回任何类型并获取任意数量参数的函数的指针
- VkSurfaceKHR 指针的值在函数调用后更改,无需任何显式赋值
- 类和构造函数中的函数根本不起作用,并且不返回任何错误
- 不执行任何操作的函数调用C++
- 如何检测除整数以外的任何内容是否传递给我的类构造函数?
- 为什么 c++ 中的 main() 函数不采用除 int 和 void 之外的任何其他返回类型
- 检查模板中 nullptr 的函数指针,了解任何类型的可调用对象
- f 是指向函数的指针,该函数采用 int,并返回指向不带任何内容并返回双精度的函数的指针
- 如何制作可以接受任何类型的参数的 std::函数和 lambda
- 在调用其析构函数之前,是否有任何实际理由检查某些东西是否可破坏?
- 给定一个 3 x 3 矩阵或任何 n x n 矩阵,为什么我的以下函数找不到对角线差异?
- 接受任何 STL 容器的函数
- C++:单向跳转到函数.任何替代方案
- 从析构函数调用虚拟函数-任何解决方法