1、软件水平考试(中级)软件设计师下午(应用技术)历年真题试卷汇编 5及答案与解析 一、必答题(共 4道大题,每道大题 15分) 1 阅读下列说明和 c+代码,将应填入 (n)处的字句写在答题纸的对应栏内。【说明】现要求实现一个能够自动生成求职简历的程序,简历的基本内容包括求职者的姓名、性别、年龄及工作经历。希望每份简历中的工作经历有所不同,并尽量减少程序中的重复代码。现采用原型模式 (Prototype)来实现上述要求,得到如图 16 1所示的类图。 【 C+代码】 #includeUsing namespace std; ClasS Cloneablepublic: (1) ; ; Class
2、 workExperience: public Cloneable 工作经历 Private: String workDate; Str ing company; PubliC: CloneableClone()(2); Obj一 workDate=this一 workDate; Obj一 company=this一 company; Return obj;其余代码省略 ; Class Resume: public Cloneable /简历 Private: String name; string sex; string age;WorkExperience。 work; Resume(Wo
3、rkExperi ence*work)(This-work: (3) ; PubliC: Resume(string name)( *实现省略 * )Void SetPersonalInfo(string sex, string age)( *实现省略 * )Void setworkExperience(string workDate, string company)( *实现省略 * )Cloneable*Clone()( 4); Obj一 name: this一 name; Obj一 sex=this一 sex; Obj一 age=this一 age; Return obj; ; Int
4、main()Resume*a=new Resume(”张三 ”); A一 SetPersonalInfo(”男 ”, ”29”); A一 setworkExperience(”1998 2000”, “XXX公司 ”); Resume*b=(5); B一 SetWorkExperience(“20012006”, “YYY公司 ”); Return 0; 2 阅读以下说明和 C+代码,将应填入 (n)处的字句写在对应栏内。【说明】欲开发一个绘图软件,要求使用不同的绘图程序绘制不同的图形。以绘制直线和圆形为例,对应的绘图程序如表 162所示。该绘图软件的扩展性要求,将不断扩充新的图形和新的绘图程
5、序。为了避免出现类爆炸的情况,现采用桥接 (Bridge)模式来实现上述要求,得到如图 162所示的类图。【 C+代码】 Class DPIpubl ic: static void draw_aline(double xl, double yl, double x2, double y2) *代码省略 * )static void drawacircle(double x, double y,double r)( *代码省略 * ); C1ass DP2(publ ic: static void drawline(double xl,double x2, double yl, double y
6、2)( *代码省略 * )static void drawcircle(double X,double Y, double r)( *代 码省略 * ); class Drawing(public: (1) ; (2) ; ;class vodrawing: publ ic Drawing(publ ic: void drawLine(double x1, double y1, double x2, double y2)( *代码省略 * )void drawCircle(double X, double Y, double r)( (3) ; ); Class vidrawing: publ
7、ic Drawingpubl ic: void drawLine(double xl,double yl, double x2, double y2)( *代码省略 * )void drawCircle(double X, double Y, double r)(4) ); C1ass Shapepubl ic: (5); Shape(Drawing*dp)(_dp=dp; )void drawLine(double x1, double yl, double x2, double y2)dp一 drawLine(x1, y1,x2, y2); )void drawCircle(double
8、X, double Y, double r)(一 dp一 drawCircle(X,Y, r); private: Drawing。 dp; ; class Rectangle: public Shapepubl ic: void draw()( *代码省略 * 其余代码省略 ; class circle: public Shapeprivate:double X, y,一 r;public: Circle(Drawing*dp, double x, double y, double r):(6)(x=x; _y=y; _r=r;)void draw()drawCircle(mX, _y, _
9、r); ); 3 阅读下列说明和 C+代码,将应填入 (n)处的字句写在答题纸的对应栏内。【说明】现欲开发一个软件系统,要求能够同时支持多种不同的数据库,为此采用抽象工厂模式设计该系统。以 SQL Server和 Access两种数据库以及系统中的数据库表Department为例,其类图如图 163所示。【 C+代码】 #includeUS ing namespace std; class Department( *代码省略 * );Class IDepartment(publ ic: (1) =0; (2) =0; Class SqlserverDepartment: (3) public:
10、 void Insert(Department*department)(cout 4 阅读下列说明 C+代码,将应填入 (n)处的字句写在答题纸的对应栏内。【说明】某咖啡店当卖咖啡时,可以根据顾客的要求在其中加入各种配料,咖啡店会根据所加入的配料来计算费用。咖啡店所供应的咖啡及配料的种类和价格如表 16 3所示。现采用装饰器 (Decorator)模式来实现计算费用的功能,得到如 图 165所示的类图。【 C+代码】 #includeincludeUSing namespace std; const int ESPRESSO_PRICE=25; const int DRAKROAST_PRIC
11、E=2 0; const int MOCHAPRICE=1 0; const int WHIP_PRICE=8; class Beverage(饮料 (1): string description; public: (2) ()(return description; )(23) ; ; class CondimentDecorator:public Beverage(配料 protected: (4);; class Espresso: public Beverage(蒸馏咖啡 publ ic: EspresSO()description: ”Espresso”; int cost()(re
12、turn ESPRESSO_PRICE; ; class DarkRoast: public Beverage(深度烘焙咖啡public: DarkRoast()(descript ion=”DardRoast”; ) int cost()(return DRAKROAST_PRICE; ); class Mocha: publ ic CondimentDecorator /摩卡public: Mocha(Beveragebeverage)(thi S一 beverage=beverage; ) string getDescription()( return beverage一 getDesc
13、ript ion()+”, Mocha”; ) int cost()( return MOCHA-pRICE+beverage一 cost(); ); class Whip: publ ic CondimentDecorator奶泡 public: Whip(Beveragebeverage) (thi S一 beverage=beverage;) string getDescription() (return beverage一 getDescription()+”, Whip”; ) int cost()(return WHIP_PRICE+beverage一 cost(); ); int
14、 main() Beverage*beverage=new DarkRoast(); beVerage=new Mocha(15); beVerage=new Whip(6); coutgetDescription()cost() 5 阅读下列说明 SDC+代码,将应填入 (n)处的字句写在答题纸的对应栏内。 【说明】 某大型商场内安装了多个简易的纸巾售卖机,自动售出 2元钱一包的纸巾,且每次仅售出一包纸巾。纸巾售卖机的状态如图 16 6所示。采用状态 (State)模式来实现该纸巾售卖机,得到如图 167所示的类图。其中类State为抽象类,定义了投币、退币、出纸巾等方法接口。类 SoldS
15、tate、SoldOutState、 NoQuarterState和 HasQuarterState分别对应图 164中纸巾售卖机的4中状态:售出纸巾、纸巾售完、没有投币、有 2元钱。【 C+代码】 #includeUSing namespace Std;以下为类的定义部分 Class TissueMachine; 类的提前引用 C1ass Statepubl iC: virtual void insertQuar七er()=0; 投币 virtual void ejectQuarter()=0; 退币 virtual void turnCrank()=0; 按下 “出纸巾 ”按钮 virtu
16、al void dispense()=0; 出纸巾 ); *类 SoldOutState、 NoQuarterState、 HasQuarterState、 SoldState的定义省略,每个类中均定义了私有数据成员 TissueMachine*tissueMachine* ClasS TiSsueMachine(private: 1*soldOutState, *noQuarterState, *hasQuartersta七 e,*soldState, *state; int count; 纸巾数 publ ic: Ti S sueMachine(int number); void setS
17、tate(State*state); State* getHasQuarterState(); State*getNoQuarterState(); State*getSoidState(); State*getS01dOurState(); int getCount(); 其余 代码省略 ; 以下为类的实现部分 void NoQuarterState:inserQuarter()( tissureMachine-setState(2) ; void HasQuarterstate: ej ectQuarter() tissureMachine-setState(3) ; void SoldS
18、tate: dispense()( i f(ti SsueMachine一 getCount()0)( tissureMachine-setState(4); e1Se tissureMachine-setState(5); /其余代码省略 6 阅读下列说明和 C+代码,将应填入 (n)处的字句写在答题纸的对应栏内。 【说明】 某公司的组织结构图如图 16 10所示,现采用组合 (Composition)设计模式来构造该公司的组织结构,得到如图 16一 11所示的类图。其 eOCompany为抽象类,定义了在组织结构图上添加 (Add)和删除 (Delete)分公司办事处或者部门的方法接口。类
19、 ConcreteCompany表示具体的分公司或者办事处,分公司或办事 处下可以设置不同的部门。类 HRDepartment和FinanceDepartment分别表示人力资源部和财务部。 【 C+代码】 #include #include #include US ing namespace std; class Company(抽象类 protected: String name; public: Company(string name)(1)=name; ) (2) ;增加子公司、办事处或部门 (3) ;删除子公司、办事处或部门 ; clasS ConcreteCompany: publ
20、ic Company( private: listchildren;存储子公司、办事处或部门 publ ic: ConcreteCompany(string name): Company(name)() void Add(Company*C)(5) push back(c);) void Delete(Company*C)6) remove(C); ) ; Class HRDepartment:public Company( public: HRDepartment(string name): Company(name)其他代码省略 ; class FinanceDepartment: pub
21、l ic Company public: FinanceDepartment(string name): Company(name)()其他代码省略 ; VOid main() ConcreteCompany*root=new ComcreteCompany(“北京总公司 ”); root一 Add(new HRDepartment(“总公司人力资源部 ”); root一 Add(new F inanceDepartment(“总公司财务部 ”); ConcreteCompany*comp=new ConcreteCompany(“上海分公司 ”); comp一 Add(new HRDepar
22、tment(“上海分公司人力资源部 ”); comp一 Add(new FinanceDepartment(“上海分公司财务部 ”); (7) ; ConcreteCompany*compl: new ConcreteCompany(“南京办事处 ”); comp 1一 Add(new HRDepartment(“南京办事处人力资源部 ”); comp 1一 Add(new FinanceDepartment(“南京办事处财务部 ”); (8);其他代码省略 软件水平考试(中级)软件设计师下午(应用技术)历年真题试卷汇编 5答案与解析 一、必答题(共 4道大题,每道大题 15分) 1 【正确答
23、案】 (I)virtual Cloneable*Clone()=0 (2)WorkExperience*obj (3)Work (4)Resume*obj (5)a一 Clone() 【试题解析】 本题考查原型模式的概念及应用,原型模型是一种对象创建模型,用 原型实体指定创建对象的种类,并且通过复制这些原型创建新的对象。原型模型允许一个对象再创建另一个可订制的对象,无需知道任何创建的细节。Prototype模式其实就是常说的 ”虚拟构造函数 ”一个实现, C+的实现机制中并没有支持这个特性,但是通过不同派生类实现的 Clone接口函数可以完成与 ”虚拟构造函数 ”同样的效果。题中声明一个虚拟基
24、类,所有的原型都从这个基类继承, (1)所代表的就是这个基类中的纯虚函数,需要供继承者自行实现,即为 virtual Cloneable*Clone()=0,首先声明一个抽象基类,并 定义 clone()函数为纯虚函数。然后根据基类实例化各个子类,并且实现复制构造函数,并实现 clone()函数,由此可知 (2)处为 WorkExperience*obj, (3)处 Work, (4)处为 Resume*obj。在 main函数中实现 Resume*b对 *am复制,故根据 C+语法 (5)中为 a一 Clone()。 【知识模块】 C+程序设计 2 【正确答案】 (1)virtual voi
25、d drawLine(double xl, double y1, double x2, double y2); (2)virtual void drawCircle(double X, double Y, double r); (3)DPI draw-a-ircle(x, y, r); (4)DP2 drawCircle(x, y, r); (5)virtual void draw(); (6)Shape(dp)。 【试题解析】 本题考查 Bridge桥接模式的概念及应用,将抽象与其实现解耦,使它们都可以独立地变化。大致意思是说:将一组实现与另一组使用他们的对象分离。这里的实现指的是抽象类及其
26、派生类用来实现自己的对象 (而不是抽象类的派生类,这些派生类被称为具体类 )Drawing是一个虚拟基类,里面包含了希望不同策略实现的算法,派生类 V1Drawing, V2Drawing都派生自 Drawing,对基类中的希望实现的算法都作了具体实现,且它们都含有 drawLine和 drawCircle函数,所以 Draw类中缺失的应该是这两个算法,于是 (1)virtual void drawLine(double x1, double y1, double x2, double y2); (2)virtual void drawCircle(double x, double y,dou
27、ble r); DPI和 DP2中包含了绘制 Line和 Circle的具体实现的 Static方法,因此在 V1Drawing, V2Drawing类中可以直接进行调用它们。 (3)DPL drawacircle(x, y, r) (4)DP2 drawCircle(x, y, r); Shape类派生出 Rectangle和 Circle类,里面都含有 draw方法,但是具体 draw方法的实现却不相同,所以 (5)virtual void draw(),最后 Circle的构造函数初始化了后 4个变量,还有继承 自 shape的变量一 dp未做初始化,因此调用 shape构造函数做初始化
28、 (6)shape(dp)。 【知识模块】 C+程序设计 3 【正确答案】 (1)virtual void Insert(Department木 department) (2)virtual Department GetDepartment(int id) (3)public IDepartment (4)public IDepartment (5)class Ifactory (6)virtual IDepartment*Create Department() 【试题解析】 本题考查抽象工厂设计模式的概念及其应用。抽象工厂设计模式的意图是:提供一个创建一系列相关或相互依赖的对象,而无须指出它
29、们具体的类。在如下情况下应当考虑使用抽象工厂模式:当一个系统要独立于它的产品的创建、组合和表示时;当一个系统要由多个产品系列中的一个来配置时;当需强调一系列相关的产品对象的设计以便进行联合使用时;想提供一组对象而不显示它们的实现过程,只显示它们的接口时。抽象工厂设计模式的类图如图 164所示,其中:Abstract Factory为抽象工厂,声明抽象产品的方法。 Concrete Factory为具体工厂,执行生成抽象产品的方法,生成一个具体的产品。 Abstract Product为抽象产品,为一种产品声明接口。 Product为具体产品,定义具体工厂生成的具体产品的对象,实现产品接口。图
30、16 3中的 IFactory对应类图中的 AbstractFactory,Sqlserverfactory和 Accessfactory对应类图中的 Concrete Factory, SqlserVer Depanment和 AccessDepartment对 应类图中 IProduct,而 IDepanment对应类图中的 Abstract Product。由于类 IDepartment的作用是为其子类提供接口,所以将其定义为抽象类。在 C+中,抽象类中至少包含一个纯虚函数的类,而纯虚函数是没有函数体的函数,其作用是为其子类提供统一的接口。若要使用纯虚函数,必须存子类中进行重置。空 (1
31、)和空 (2)考查的是如何定义抽象类IDepartment。从 IDepartment的子类的方法中可以确定空 (1)处应填 Avirtual void Insert(Department*department),空 (2)处应填 Avirtual DepartmentGetDepartment(int id)。空 (3)和空 (4)考查继承的概念和语法。由于SqlserverDepartment和 AccessDepanment均继承 IDepartment,因此,空 (3)和空(4)都应填 ), public IDepartment。由于所给程序中缺少有关抽象类 IFactory的定义,因
32、此空 (5)处应为定义类 IFactory,应填 Aclass IFactory。抽象类 IFactoryq少需包含一个纯虚函数的 类,由其子类 sqlserVerfactory和 Accessfactory中方法的定义可知, (6)处应填入 virtual IDepartment*CreateDepartmentO。 【知识模块】 C+程序设计 4 【正确答案】 (1)abstract(2)StringgetDescription(3)abstractintcost() (4)Beveragebeverage(5)beverage(6)beverage 【试题解析】 由类图可知, Bever
33、age是基类, Espresso、 DarkRoast、CondimentDecorator是 Beverage的派生类, Mocha、 Whip又是CondimentDecorator的派生类。 (1)处应填 kdescfiption访问控制类型,可能为 private或 protected。在Beverage派生类 Espressol )-始化函数中直接使用 “description,由此可知,在基类中, description访问控制类型为 protected。如果为 priVate,则在派生中不能使用。 在基类中先后动态建立了 一个 DarkRoast对象、 Mocha对象和 Whip
34、对象,调用初始化函数,并输出。在 Mocha类和 Whip类中分别调用了基类的getDescription()cost()。 【知识模块】 C+程序设计 5 【正确答案】 (1)State (2)tissueMachine-getHasQuarterState0或 new HasQuarterState (3)tissueMachine-getNoQuarterState0或 new NoQuarterState (4)tissueMachine-getNoQuarterState0或 new NoQuarterState (5)tissueMachine-getS0ldoutState()或
35、 new So|dOutState 【试题解析】 (1)根据题意,本题使用的是状态模式,判断纸巾售卖机的状态,根据不同的状态执行不同的动作。 State定义了纸巾售卖机所对应的一些状态,售出纸巾、纸巾售完等状态。类 SoldOutState、 NoQuarterState、HasQuarterState、 SoldState均有类 State派生而来。 (2)void insertQuarter()定义了一个 “投币 ”的方法:在没有 “2元钱 ”时,客户投币的方法。 tissureMachine setState是改变纸巾售卖机的状态,此时,客户已投入 2元钱,故将此时的状态改为 “有 2元
36、钱 ”的状态,纸巾售卖机调用 “有 2元钱 ”状态的方法即可。 (3)void ejectQuarter0定义了一个 “退币 ”的方法:在有 2元钱的状态下,用户按下退币按钮,纸巾售卖机将此时的状态改为 “没有投币 ”状态,故直接调用getNoQulnerState()即可。 (4)根据 纸巾售卖机状态图可知,当售出纸巾,并且纸巾数量仍大于 0时,将返回 “没有投币 ”状态,同第 (3)小题的分析,此处应调用 getNoQuarterState0。 (5)根据纸巾售卖机状态图可知,当售出纸巾,并且纸巾数量等于 0时,将返回“纸巾售完 ”状态,此处用了 ifelse 判断语句,当纸巾数量仍大于
37、0时,返回 “没有投币 ”状态,否则,纸巾数量一定等于 0,本段程序第 (5)空是 else下的一条语句,故此处是判断 count为 0时,纸巾售卖机的状态,显然,应调用getSoldOutState0。 【知识模块】 C+程序设计 6 【正确答案】 (1)this一 name (2)virtual void Add(Company*c)=0 (3)virtual void Delete(Company*C)=0 (4)Company* (5)Children (6)Children (7)root一 Add(comp) (8)comp一 Add(compl) 【试题解析】 初始化函数中,将形
38、参的值付给成员 name,形参的变量名和成员变量的名称相同,需要使 this指针指示被赋值的 name是类的成员。增加 (删除 )子公司、办事处或部门用到的函数是 Add和 Delete。由于 C0mpany是抽象类,并作为 ConcreteCompany、 HRDepartment、 FinanceDepartment的基类,ConcreteCompany、 HRD印 anment继承了其父类的 Add和 Delete操作,因此在基类中要将 Add和 DeIete设置为纯虚函数。类 ConcreteCompany表示具体的分公司或者办事处,其中的成员 children用来存储子公司、办事处或部门,其数据类型应为 Company*,当进行增加操作时,要把增加的对 象存储在 children的最后;当进行删除操作,则需要从 children中将对应的对象移除。 (7)处的操作是把上海分公司这个对象加入到北京公司总部中。 (8)处的操作是将南京办事处这个对象加入到上海分公司中。 【知识模块】 C+程序设计