2013年上半年软件设计师C++题答案与分析

2013年上半年软件设计师C++题答案与分析

 

       昨天刚考了软件设计师,由于目前我正在学习C++的使用,所以对下午的C++试题比较感兴趣,回来就根据记忆,把自己的答案,写了出来,然后重新推理了一下源程序,测试编译运行,最后对答案进行了分析。

      原题意是写一个自动写简历的程序,是按原型模式进行设计的。
      根据记忆整理,并进行改动后可以编译运行的程序如下:

#include <iostream>
#include <string>
using namespace std;

class Cloneable
{
public:
 //(1);
 virtual Cloneable * Clone() = 0 ;
};

class WorkExperience : public Cloneable
{
private:
 string time;
 string workExp;
public:
 int setTime(string time){
  this->time=time;
  cout << "WorkExperience setTime:" << time << endl ;  
 }
 int setWorkExp(string workExp){}
 Cloneable * Clone()
 {
  cout << "WorkExperience" << " Clone" << endl;
  //(2);
  WorkExperience * obj = new WorkExperience();
  obj->time=this->time;
  obj->workExp=this->workExp;
  cout << "WorkExperience" << " Clone ok." << endl;
  return obj;
 }
};

class Resume : public Cloneable
{
private:
 string name,sex;
 int age;
 WorkExperience * work;
 Resume(WorkExperience * work)
 {
  cout << "Resume :" << " Resume(WorkExperience)"  << endl;
  //this->work=(3);
  this->work=(WorkExperience *)(work->Clone());//work;//
 }
public:
 Resume(string name){
  cout << "Resume " << " Resume(" << name << ")" << endl;
  this->name=name;
  this->work=NULL;  
  this->age=-1;
 }
 ~Resume(){
  cout << "Resume " << " destructor " <<  endl;  
  if(work!=NULL)
  {
   delete work;
   cout << "Resume " << " delete work " <<  endl;  
  }  
 }
 int setSex(string sex){
  this->sex=sex;
  cout << "Resume setSex:" << sex << endl ;  
 }
 int setAge(int age){
  this->age=age;
  cout << "Resume setAge:" << age << endl ;  
 }
 int setWorkExperience(WorkExperience * work){
  cout << "Resume " << " setWorkExperience" << endl;
  this->work=(WorkExperience *)(work->Clone());
 }
 Cloneable * Clone()
 {
  cout << "Resume " << "Clone" << endl;
  //(4);
  Resume * obj = new Resume(this->work);
  obj->name=this->name;
  obj->sex=this->sex;
  obj->age=this->age;
  cout << "Resume " << "Clone ok." << endl;
  return obj;
 }
};

int main()
{
 
 cout << "Prototype test" << endl ;

 Resume * a= new Resume("lintax");
 WorkExperience * work=new WorkExperience();
 a->setSex("男");
 a->setAge(36);
 work->setTime("2000-2003");
 a->setWorkExperience(work);
 work->setTime("2003-2005");
 a->setWorkExperience(work);
 //Resume * b= (5);
 Resume * b= (Resume *)a->Clone();

 work->setTime("2005-2013");
 b->setWorkExperience(work);
 delete b;
 delete a;
 delete work; 
 return 0;
}


下面给出我分析后的答案:

1、virtual Cloneable * Clone() = 0
2、WorkExperience * obj = new WorkExperience()
3、(WorkExperience *)(work->Clone())
4、Resume * obj = new Resume(this->work)
5、(Resume *)(a->Clone())

分析如下:
1,C++题考虚函数似乎是惯例了,做过往年真题的同学应该有体会的。类Cloneable 基本上就是一个接口类,他的主要用途就是声明一个Clone()函数,这个其实也是原型模式的概念所在,就是实现拷贝。由于希望所有子类进行重写Clone()函数,所以定义为虚函数。具体函数名、返回类型什么的,参考子类里面的Clone函数的实现就可以知道了。

2,在WorkExperience 的Clone函数种,obj没有定义就开始使用了,不合理,所以就需要在空白处进行定义。定义为什么类型?看obj有WorkExperience类的成员,那么也就确定obj即WorkExperience类的对象。由于Clone函数没有传入的参数,而要传出obj,则obj需要有真实指向的内容,就需要new一个了。

3,这个题我开始一看,很明显的一个赋值操作,似乎函数也非常简单,也没有其它输入参数 ,好像直接赋值work就行了。这样编译也是可以通过的。可是,考官会给我们送分吗?只怕没有那么幸福的事情。再联系原型模式的概念,它是要进行完整的拷贝,而不是仅仅指向就行了的。所以,这里要进行一次Clone。这里又要注意,对于C++,编译是比较严格的,等号前后的类型若不匹配,是会编译报警甚至报错的。这里,我添加了强制类型转换,不清楚考官会否要求类型匹配。

4,这题与第2题类似,可是不要掉以轻心,Resume提供了两个构造函数,考虑到Resume类的Clone函数要实现全部内容的拷贝,所以只能选择前一个构造函数Resume(WorkExperience * work)。参数选择,个人感觉使用work或者this->work都可以,因为在这个函数里面,并没有关于work名字的冲突问题。

5,这题与第3题类似,不过要注意的,一个是类型匹配,很容易被忽略的。另外一点是其选择范围更大,似乎也可以新建一个类,可是这样,就与题意不相符了。使用一次Clone,是将前面简历的内容拷贝了一份,在新生成的Resume对象里面,就有了所有原来的对象(a)的内容,又可以继续添加新的内容,且新的对象b没有对原对象a的依赖--即对象a即使删除了,也不影响对象b的继续使用。

      不分析不知道,一分析吓一跳,根据我的分析,我竟然已经错了两个,本来还以为已经考虑的比较充分了,原来还是不够小心啊!
      总的感觉,每一题都考到了不同的内容,题目的难度是一年比一年大了。

      以上,仅供参考,欢迎讨论。

 

 

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值