作业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的参数,跟第二题差不多,只不过这是多态的第一种情况,通过指针来实现。

posted @ 2020-03-22 16:23  timeaftertime  阅读(217)  评论(0编辑  收藏  举报