第十二周 阅读项目 (5)

来源:互联网 发布:完美世界 小说 知乎 编辑:程序博客网 时间:2024/06/06 02:14
阅读下面类的定义,请说出在测试函数中不同情况的调用产生的结果
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3. class A  
  4. {  
  5. protected:  
  6.     int a,b;  
  7. public:  
  8.     A(int aa, int bb):a(aa), b(bb) {}  
  9.     void printA()  
  10.     {  
  11.         cout<<"a: "<<a<<"\tb: "<<b<<endl;  
  12.     }  
  13. };  
  14. class B: public A  
  15. {  
  16.     int c;  
  17. public:  
  18.     B(int aa, int bb, int cc):A(aa,bb),c(cc) {}  
  19.     void printB()  
  20.     {  
  21.         cout<<"a: "<<a<<"\tb: "<<b<<"\tc: "<<c<<endl;  
  22.     }  
  23. };  
  24. int main()  
  25. {  
  26.     A a(1,1);  
  27.     B b(2,3,4);  
  28.     //此处加入下面各小题中的代码  
  29.     return 0;  
  30. }  

(a)
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. a=b;  
  2. a.printA();  
  3. b.printA();  
  4. b.printB();  
你认为输出结果是:__________ ____________
运行程序的结果是:______________________


(b)
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. b=a;  
  2. a.printA();  
  3. b.printA();  
  4. b.printB();  
程序会发生编译错误,原因是:__________
记录下IDE中提示的错误并理解:_________
只能用子类对象对基类对象赋值,而不用基类对象对其子类对象赋值。
同一基类的不同派生类对象之间也不能赋值。
(c)
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. A &r1=a;  
  2. A &r2=b;  
  3. r1.printA();  
  4. r2.printA();  
  5. r2.printB();  
将会发生错误的一行删除;
对余下的程序,你认为输出是:__________
实际运行的输出是:____________________
那一行的错误原因是:__________________
删除后运行结果:

(d)
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. A *p=&a;  
  2. p->printA();  
  3. p=&b;  
  4. p->printA();  
  5. p->printB();  
将会发生错误的一行删除;
对余下的程序,你认为输出是:__________
实际运行的输出是:____________________
那一行的错误原因是:__________________

(e)
在class A中增加成员函数:
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. int getA(){return a;}  
在main函数前增加一般函数:
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. void f(A x)  
  2. {  
  3.     cout<<"aaaaah, my a: "<<x.getA()<<endl;  
  4. }  
main函数中指定部分为:
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. f(a);  
  2. f(b);  
你认为输出结果是:______________________
运行程序的结果是:______________________


补充阅读
[cpp] view plaincopyprint?在CODE上查看代码片派生到我的代码片
  1. #include <iostream>  
  2. using namespace std;  
  3. class B  
  4. {  
  5. public:  
  6.     B(int x=0)  
  7.     {  
  8.         X=x;  
  9.         cout<<"B("<<x<<")\n";  
  10.     }  
  11.     ~B()  
  12.     {  
  13.         cout<<"~B()\n";  
  14.     }  
  15.     void print()  
  16.     {  
  17.         cout <<X<< " ";  
  18.     }  
  19. private:  
  20.     int X;  
  21. };  
  22.   
  23.   
  24. class D: public B  
  25. {  
  26. public:  
  27.     D (int x, int y):B(x)  
  28.     {  
  29.         Y=y;  
  30.         cout<<"D("<<x<<","<<y<<")\n";  
  31.     }  
  32.     ~D()  
  33.     {  
  34.         cout<<"~D()\n";  
  35.     }  
  36.     void print()   //与基类中的成员函数同名!这个冲突如何解决的?!  
  37.     {  
  38.         B::print();  
  39.         cout <<Y<<endl;  
  40.     }  
  41. private:  
  42.     int Y;  
  43. };  
  44. int  main()  
  45. {  
  46.     D d(11,22);  
  47.     d.print();  
  48.     return 0;  
  49. }  
运行结果:



总体来说,结合了组合和继承的c++类中,构造函数和析构函数的调用顺序具有以下规律:

1、对于继承:如果有基类,首先构造指定类的基类;

2、对于组合:按照嵌入的成员对象的声明顺序构造它们,成员对象构造完成后再构造封装它们的这个类;

3、构造和析构本身依赖于压栈和出栈,因此析构函数的函数的调用应该遵循栈的特性,以“后进先出”为原则——析构函数的调用与构造函数完全相反,先构造的后析构,后构造的先析构;


0 0