《C++面向对象程序设计》第6章课后编程题2拓展

    设计一个程序,其中有3个类CBank、BBank、GBank,分别为中国银行类,工商银行类和农业银行类。每个类都包含一个私有数据成员balance用于存放储户在该行的存款数,另有一个友元函数Total用于计算储户在这3家银行中的总存款。类结构图如图6-1所示。

172545_xrPp_3866255.jpg

    因为觉得类的私有数据成员只有balance太不正常了,因此增加了成员Id和Key,分别表示账户号码和密码。只有当三个银行的Id和Key都相同时,用户才能访问balance成员,Total函数才能成功执行。

代码如下:

  1. #include<iostream>
  2. using namespace std;
  3. #include<string>
  4. class BBank;
  5. class GBank; //Total同时是三个类的友元函数,必须在创建类前先声明所有类
  6. class CBank //CBank类的声明
  7. {public:
  8. CBank(char*,char*,double); //构造函数原型声明
  9. friend void Total(CBank &,BBank &,GBank &); //声明Total函数为CBank类的友元函数
  10. private:
  11. char id[30]; //账户名
  12. char key[6]; //6位密码
  13. double balance; //银行存款
  14. };
  15. CBank::CBank(char Id[30],char Key[6],double Balance) //构造函数的类外定义
  16. {
  17. for(int i=0;i<30;i++)
  18. id[i]=Id[i];
  19. for(int j=0;j<6;j++)
  20. key[j]=Key[j];
  21. balance=Balance;
  22. }
  23. class BBank //BBank类的声明
  24. {public:
  25. BBank(char*,char*,double); //构造函数原型声明
  26. friend void Total(CBank &,BBank &,GBank &); //声明Total函数为BBank类的友元函数
  27. private:
  28. char id[30];
  29. char key[6];
  30. double balance;
  31. };
  32. BBank::BBank(char Id[30],char Key[6],double Balance) //构造函数原型声明
  33. {
  34. for(int i=0;i<30;i++)
  35. id[i]=Id[i];
  36. for(int j=0;j<6;j++)
  37. key[j]=Key[j];
  38. balance=Balance;
  39. }
  40. class GBank //GBank类的声明
  41. {public:
  42. GBank(char*,char*,double);
  43. friend void Total(CBank &,BBank &,GBank &); //声明Total函数为GBank类的友元函数
  44. private:
  45. char id[30];
  46. char key[6];
  47. double balance;
  48. };
  49. GBank::GBank(char Id[30],char Key[6],double Balance) //构造函数原型声明
  50. {
  51. for(int i=0;i<30;i++)
  52. id[i]=Id[i];
  53. for(int j=0;j<6;j++)
  54. key[j]=Key[j];
  55. balance=Balance;
  56. }
  57. void Total(CBank &c,BBank &b,GBank &g) //友元函数,c、b、g分别为CBank、BBank、GBank类对象的引用
  58. {
  59. int s=0;
  60. for(int i=0;i<30;i++)
  61. {
  62. if(c.id[i]==b.id[i] && c.id[i]==g.id[i] && b.id[i]==g.id[i])
  63. {
  64. for(int j=0;j<6;j++)
  65. {
  66. if(c.key[j]==b.key[j] && c.key[j]==g.key[j] && b.key[j]==g.key[j])
  67. {
  68. s=1; //完全正确,结果s赋值为1
  69. continue; //继续循环判断
  70. }
  71. else
  72. {
  73. s=2; //账户号码正确 ,但密码错误,结果赋值为2
  74. break; //跳出循环判断
  75. }
  76. }
  77. }
  78. else
  79. {
  80. s=3; //账号信息完全不符,结果赋值为3
  81. break; //跳出循环判断
  82. }
  83. }
  84. switch(s) //判断结果类型
  85. {
  86. case 1:
  87. cout<<"总存款为:"<<endl;
  88. cout<<c.balance<<"+"<<b.balance<<"+"<<g.balance<<"="<<c.balance+b.balance+g.balance<<"元"<<endl;
  89. break;
  90. case 2:
  91. cout<<"账号密码错误!"<<endl;
  92. break;
  93. case 3:
  94. cout<<"账号名称不符!"<<endl;
  95. break;
  96. default:
  97. cout<<"发生未知错误,请联系银行客服!"<<endl;
  98. break;
  99. }
  100. }
  101. int main()
  102. {
  103. CBank c("张三","111111",2536);
  104. BBank b("张三","111111",11365);
  105. GBank g("张三","111111",88565);
  106. Total(c,b,g);
  107. getchar(); getchar();
  108. return 0;
  109. }

运行结果:

195856_Qj9Z_3866255.png

编写程序时遇到的一些问题及解决思路历程:

    关于循环判断的问题:一开始我的Total函数是这样写的:

  1. void Total(CBank &c,BBank &b,GBank &g)
  2. {
  3. for(int i=0;i<30;i++)
  4. {
  5. if(c.id[i]==b.id[i] && c.id[i]==g.id[i] && b.id[i]==g.id[i])
  6. {
  7. for(int j=0;j<6;j++)
  8. {
  9. if(c.key[j]==b.key[j] && c.key[j]==g.key[j] && b.key[j]==g.key[j])
  10. {
  11. cout<<"总存款为:"<<endl;
  12. cout<<c.balance<<"+"<<b.balance<<"+"<<g.balance<<"="<<c.balance+b.balance+g.balance<<"元"<<endl;
  13. }
  14. else
  15. cout<<"账号密码错误!"<<endl;
  16. }
  17. }
  18. else
  19. cout<<"账号信息不符!"<<endl;
  20. }
  21. }

运行结果:

200139_N1rQ_3866255.png

    和预期的不同,出现了30次结果。回到代码,发现好像也解释得通:要判断Id和Key数组中每个元素的情况,必然用到循环语句;可只要第i个元素相同,满足条件,就会执行cout输出操作。

    请教了老师,他建议我自定义一个布尔函数进行判断,若循环内能满足所有判断条件,则返回true,否则返回false。我自定义了一个Verify函数,代码如下:

  1. bool Verify(char a[30],b[6])
  2. {
  3. for(int i=0;i<30;i++)
  4. {
  5. if(c.id[i]==b.id[i] && c.id[i]==g.id[i] && b.id[i]==g.id[i])
  6. {
  7. for(int j=0;j<6;j++)
  8. {
  9. if(c.key[j]==b.key[j] && c.key[j]==g.key[j] && b.key[j]==g.key[j])
  10. return true;
  11. }
  12. else
  13. return false;
  14. }
  15. }
  16. int main()
  17. {
  18. CBank c("张三","111111",2536);
  19. BBank b("张三","111111",11365);
  20. GBank g("张三","111111",88565);
  21. if(Verify(Id[30],Key[6]))
  22. {
  23. cout<<"总存款为:"<<endl;
  24. cout<<c.balance<<"+"<<b.balance<<"+"<<g.balance<<"="<<c.balance+b.balance+g.balance<<"元"<<endl;
  25. }
  26. else cout<<"账号信息错误!"<<endl;
  27. return 0;
  28. getchar(); getchar();
  29. }

发现又出现了新的问题:   

 一、  Id和Key都是类的私有成员,Verify函数无法访问它们。

 二、  Verify函数是在main主函数中运行的,但该函数判断完后还有输出语句需访问类的私有成员。

 三、  bool函数结果只有两种结果,无法反映多结果的情况。

    问题一的解决思路:

                1. 将Verify函数定义为类的友元函数。

                2.将Verify的参数改成6个字符串类型,对应3个银行的Id和Key数组。

    问题二的解决思路:自定义一个输出函数,它是三个类的公共友元函数。

    问题三的解决思路:不使用bool型,而改用switch语句判断。

综合三个问题的思路,得出两个解决办法

方法一:

    自定义bool型判断函数和void型输出函数,他们都是三个类的友元函数,都能访问三个类的私有成员。void型输出函数根据bool型判断函数的返回值输出不同结果。

方法二:

    在原Total函数中,利用bool型返回值判断的思路,定义一个变量s作为返回值。根据循环判断结果赋给s不同的值,再根据s的值输出不同的结果。开头给出的函数就是使用了法二。

总结:

    两种方法都可行,两者的时间复杂度相同。但法一较法二不能做到解决问题三的优化,因此法二有更大的可拓展性和适应性。

转载于:https://my.oschina.net/humbledew/blog/1817628

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值

举报

选择你想要举报的内容(必选)
  • 内容涉黄
  • 政治相关
  • 内容抄袭
  • 涉嫌广告
  • 内容侵权
  • 侮辱谩骂
  • 样式问题
  • 其他
点击体验
DeepSeekR1满血版
程序员都在用的中文IT技术交流社区

程序员都在用的中文IT技术交流社区

专业的中文 IT 技术社区,与千万技术人共成长

专业的中文 IT 技术社区,与千万技术人共成长

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

关注【CSDN】视频号,行业资讯、技术分享精彩不断,直播好礼送不停!

客服 返回顶部