• 作业6-多态


    以后做完题一定要及时总结到博客里……不要拖着orz

    而且我觉得作业都留的太巧妙了,不写作业掌握的都是假知识

    1.看上去是多态

     1 //程序填空产生指定输出
     2 /*
     3 输出
     4 D::Fun
     5 B::Fun
     6 D::Fun
     7 nBVal=2
     8 nBVal=24
     9 nDVal=8
    10 B::Fun
    11 nBVal=12
    12 */ 
    13 #include <iostream>
    14 using namespace std;
    15 class B { 
    16     private: 
    17         int nBVal; 
    18     public: 
    19         void Print() 
    20         { cout << "nBVal="<< nBVal << endl; } 
    21         void Fun() 
    22         {cout << "B::Fun" << endl; } 
    23         B ( int n ) { nBVal = n;} 
    24 };
    25 // 在此处补充你的代码
    26 class D:public B{ 
    27     int nDVal;
    28     public: 
    29         void Print() 
    30         {     
    31             B::Print(); //覆盖,调用基类函数时要加B:: 
    32             cout << "nDVal="<< nDVal << endl; 
    33         } 
    34         void Fun() 
    35         {cout << "D::Fun" << endl; } 
    36         D ( int n ):nDVal(n),B(3*n){} 
    37 };
    38 int main() { 
    39     B * pb; D * pd; 
    40     D d(4); d.Fun(); 
    41     pb = new B(2); pd = new D(8); 
    42     pb -> Fun(); pd->Fun(); 
    43     pb->Print (); pd->Print (); //默认调用的是D中的Print 
    44     pb = & d; pb->Fun(); //为啥调用的是B的函数? 通过指针调用成员函数,只跟指针类型有关系
    45     pb->Print(); 
    46     return 0;
    47 }

    备注:这道题叫看上去是多态实际上就不是多态。对于不是多态的情况,如果派生类和基类里有同名函数,就是覆盖关系,这是第五讲的内容,结果我都忘了……如果是派生类默认调用的是派生类的成员函数。对于非多态来说,通过指针调用成员函数,只跟指针类型有关系,也就是说指针类型决定了调用的是基类还是派生类的成员函数。我猜这道题的含义是,老师为了让我们体会多态的意义。因为不用多态,就不能实现用基类指针调用派生类的虚函数。

    2.Fun和Do

     1 /*A::Fun
     2 C::Do*/ 
     3 #include <iostream> 
     4 using namespace std;
     5 class A { 
     6     private: 
     7     int nVal; 
     8     public: 
     9     void Fun() 
    10     { cout << "A::Fun" << endl; }; 
    11     void Do() 
    12     { cout << "A::Do" << endl; } 
    13 }; 
    14 class B:public A { 
    15     public: 
    16     virtual void Do() 
    17     { cout << "B::Do" << endl;} 
    18 }; 
    19 class C:public B { 
    20     public: 
    21     void Do( ) 
    22     { cout <<"C::Do"<<endl; } 
    23     void Fun() 
    24     { cout << "C::Fun" << endl; } 
    25 }; 
    26 /*函数的参数传入的是B &p,
    27 Fun函数没有多态,执行的是A(B中没有Fun这个函数,所以调用的是基类中的Fun,Do函数多态,执行的是C::Do*/
    28 void Call(//输入代码 派生类对象可以赋值给基类引用,然后看看是函数不是多态 
    29  B &p
    30  ) { 
    31     p.Fun(); p.Do(); 
    32 } 
    33 int main() { 
    34     C c; 
    35     Call( c); 
    36     return 0;
    37 }

    备注:这道题就让填一个参数。这是多态的第二种应用,就是派生类对象可以赋值给基类引用。这道题里Call的实参就是一个B类对象,对于Fun函数来说,Fun不是多态,并且B中没有Fun函数,所以调用的就是A中的;对于虚函数Do来说,p.Do()就是多态,这时发现p是一个C类对象,所以调用的是C类的Do函数。

    3.这是什么鬼delete

     1 /*
     2 destructor B
     3 destructor A
     4 */ 
     5 #include <iostream> 
     6 using namespace std;
     7 class A 
     8 { 
     9 public:
    10     A() { }
    11 // 在此处补充你的代码
    12     virtual ~A(){ cout << "destructor A" << endl; } 
    13 }; 
    14 class B:public A { 
    15     public: 
    16     ~B() { cout << "destructor B" << endl; } 
    17 }; 
    18 //我们知道一般析构顺序是派生类到基类,但是如果是基类的指针指向派生类,
    19 //如果基类的析构函数不设置为虚函数,那么就程序就只会调用基类的析构函数,不会调用派生类的析构函数
    20 //考察虚析构函数,一个类作为基类,析构函数应该设为虚函数 
    21 int main() 
    22 { 
    23     A * pa; 
    24     pa = new B; 
    25     delete pa; 
    26     return 0;
    27 }

    备注:

    这道题就是考察虚析构函数,一个类作为基类,析构函数应该设为虚函数。

     

     4.怎么又是Fun和Do

     1 /*
     2 A::Fun
     3 A::Do
     4 A::Fun
     5 C::Do
     6 */ 
     7 #include <iostream>
     8 using namespace std;
     9 class A {
    10     private:
    11     int nVal;
    12     public:
    13     void Fun()
    14     { cout << "A::Fun" << endl; };
    15     virtual void Do()
    16     { cout << "A::Do" << endl; }
    17 };
    18 class B:public A {
    19     public:
    20     virtual void Do()
    21     { cout << "B::Do" << endl;}
    22 };
    23 class C:public B {
    24     public:
    25     void Do( )
    26     { cout <<"C::Do"<<endl; }
    27     void Fun()
    28     { cout << "C::Fun" << endl; }
    29 };
    30 void Call(
    31 // 在此处补充你的代码
    32 A*p
    33 ) {
    34     p->Fun(); p->Do();
    35 }
    36 int main() {
    37     Call( new A());
    38     Call( new C());
    39     return 0;
    40 }

    备注:这道题又是填Call的参数,跟第二题差不多,只不过这是多态的第一种情况,通过指针来实现。

  • 相关阅读:
    冲刺2 05
    冲刺02 04
    人月神话阅读笔记01
    进度条
    团队冲刺第十天
    团队冲刺第九天
    学习进度条13
    团队冲刺第八天
    怎样买书更便宜
    冲刺第七天
  • 原文地址:https://www.cnblogs.com/fangziyuan/p/12546706.html
Copyright © 2020-2023  润新知