工程8-1 创建一个帮助类
如果我们使用一句话来总结类的本质,那就是:类封装了功能。通常,类只是构建大型程序的基本元素。因此每个类都应该是一个功能明确且单一的逻辑体,而且类要尽可能的小,小的不能再小了!也就是说含有冗余功能的类不够明确并且也破坏了代码的结构。但是含有太多过小功能的多个类有显得过于凌乱。那么如何来平衡了?正是这一点使得编程成为了一种艺术!幸运的是,随着程序员编程经验的不断增加,这种艺术性的工作会变得越来越简单。
下面我们就改写第三篇章中的工程3-3,将其修改为一个帮助类。通过这个例子来丰富大家的编程经验。这样做有什么好处了?首先,整个帮助类定义了一个逻辑单元:简单地显示出C++中控制语句的语法。因此其功能的定义是相当紧凑和单一的。其次,这种封装帮助功能成一个类的方式是非常让人赏心悦目的。无论我们需要在什么时候提供相关的帮助系统给用户,我们只需要提供它的一个实例即可。最后,由于帮助功能被封装成一个类了,必要的时候我们可以对其进行升级或者修改,而这些完全不会给使用这个类的用户带来任何的副作用。
步骤:
1. 创建一个新的文件,命名为HelpClass.cpp。为了节省时间,我们可以把项目3-3中的代码复制过来。
2. 为了把帮助系统封装成一个类,我们必须先明确地定义帮助系统都由什么组成。例如,在Help3.cpp中,有代码来显示菜单,有代码来提示用户进行选择,有代码来检查用户的输入是否有效,还有代码来显示用户选择的信息。程序循环直到用户键入p。仔细考虑一下就会发现,显示菜单,检查用户的输入并显示帮助信息给用户都是帮助类中不可缺少的组成部分;而如何获取用户的输入以及是否需要重复循环都不是帮助类的组成部分。因此,我们的类中必须包含显示帮助信息,显示帮助菜单,检查用户选择是否有效的功能。这些函数我们分别称之为:helpon(),showmenu()和isvalid()。
3. 按照下面的代码来声明Help类:
//封装了帮助功能的类
class Help
{
public:
void helpon(char what);
void showmenu();
bool isvalid(char ch);
};
请注意,这个类是一个只含有成员函数的类,我们此时不需要实例变量。正如我们在前面解释的那样,只含有数据或者只含有函数的类是完全合法的。
4. 按照下面代码所示来创建helpon()函数:
//显示帮助信息
void Help::helpon(char what)
{
switch(what)
{
case '1':
{
cout << "The if :\n\n";
cout << "if (conditaion) statement;\n";
cout << "else statement;\n";
break;
}
case '2':
{
cout << "The switch:\n\n";
cout << "switch(expression)\n";
cout << "{\n";
cout << " case constant:\n";
cout << " statement sequence\n";
cout << " break;n";
cout << " \\...\n";
cout << "}\n";
break;
}
case '3':
{
cout << "The for:\n\n";
cout << "for(init;condition;increment)\n";
cout << "{\n";
cout << " statement\n";
cout << "}\n";
break;
}
case '4':
{
cout << "The while:\n\n";
cout << "while(condition) statement;\n";
break;
}
case '5':
{
cout << "The do-while:\n\n";
cout << " do\n";
cout << " {\n";
cout << " statement;\n";
cout << " }while(condition)\n";
break;
}
case '6':
{
cout << "The break:\n\n";
cout << "break;\n";
break;
}
case '7':
{
cout << "The continue:\n\n";
cout << "continue;\n";
break;
}
case '8':
{
cout << "The goto:\n\n";
cout << "goto label;\n";
break;
}
}
}
5. 按照下面的代码创建showmenu()函数:
//显示帮助菜单
void Help::showmenu()
{
cout << "Help on:\n";
cout << " 1. if\n";
cout << " 2. switch\n";
cout << " 3. for\n";
cout << " 4. while\n";
cout << " 5. do-while\n";
cout << " 6. break\n";
cout << " 7. continue\n";
cout << " 8. goto\n";
cout << "Choose one (q to quit):";
}
6. 按照下面的代码创建isvalid()函数:
//如果选择是有效的,则返回true
bool Help::isvalid(char ch)
{
if ( ch < '1' || ch > '8' && ch != 'q' )
return false;
else
return true;
}
7. 重写其中的main()函数。完成后的最终代码如下:
/* 工程8-1
把工程-3转换为一个Help类
*/
#include <iostream>
using namespace std;
//封装了帮助功能的类
class Help
{
public:
void helpon(char what);
void showmenu();
bool isvalid(char ch);
};
//显示帮助信息
void Help::helpon(char what)
{
switch(what)
{
case '1':
{
cout << "The if :\n\n";
cout << "if (conditaion) statement;\n";
cout << "else statement;\n";
break;
}
case '2':
{
cout << "The switch:\n\n";
cout << "switch(expression)\n";
cout << "{\n";
cout << " case constant:\n";
cout << " statement sequence\n";
cout << " break;\n";
cout << " \\...\n";
cout << "}\n";
break;
}
case '3':
{
cout << "The for:\n\n";
cout << "for(init;condition;increment)\n";
cout << "{\n";
cout << " statement\n";
cout << "}\n";
break;
}
case '4':
{
cout << "The while:\n\n";
cout << "while(condition) statement;\n";
break;
}
case '5':
{
cout << "The do-while:\n\n";
cout << " do\n";
cout << " {\n";
cout << " statement;\n";
cout << " }while(condition)\n";
break;
}
case '6':
{
cout << "The break:\n\n";
cout << "break;\n";
break;
}
case '7':
{
cout << "The continue:\n\n";
cout << "continue;\n";
break;
}
case '8':
{
cout << "The goto:\n\n";
cout << "goto label;\n";
break;
}
}
}
//显示帮助菜单
void Help::showmenu()
{
cout << "Help on:\n";
cout << " 1. if\n";
cout << " 2. switch\n";
cout << " 3. for\n";
cout << " 4. while\n";
cout << " 5. do-while\n";
cout << " 6. break\n";
cout << " 7. continue\n";
cout << " 8. goto\n";
cout << "Choose one (q to quit):";
}
//如果选择是有效的,则返回true
bool Help::isvalid(char ch)
{
if ( ch < '1' || ch > '8' && ch != 'q' )
return false;
else
return true;
}
int main()
{
char choice;
Help hlpob; //创建一个Help类的对象
//使用Help对象来显示信息
for(;;)
{
do
{
hlpob.showmenu();
cin >> choice;
}while(!hlpob.isvalid(choice));
if ( choice == 'q' )
break;
hlpob.helpon(choice);
}
return 0;
}
我们运行上面的程序,发现它的功能和前面的第三篇中的工程3-3是一样的。这样封装成类的方法的好处就是我们现在有了一个可以复用的帮助系统构件。我们可以在任何需要的地方使用它。