第49课 多态的概念和意义

Posted wanmeishenghuo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了第49课 多态的概念和意义相关的知识,希望对你有一定的参考价值。

上一节中,函数重写遇上赋值兼容出现了问题:

技术分享图片

34、35行调用的都是父类中的print函数。

35行我们给的实参是Child对象,期望调用子类中的print函数,但是运行结果并不是这样。

函数重写回顾:

技术分享图片

子类中重定义父类中已有的函数,就是因为父类中的函数满足不了我们的需求。

我们期望的是只要是子类对象,调用的都是子类中的函数版本。

即使将子类对象赋值给父类指针或者引用,调用同名函数时我们也期望调用的是子类中的版本。

 

多态的概念和意义:

技术分享图片

多态:

技术分享图片

 

技术分享图片

 

示例程序:

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 class Parent
 7 {
 8 public:
 9     virtual void print()
10     {
11         cout << "I‘m Parent." << endl;
12     }
13 };
14 
15 class Child : public Parent
16 {
17 public:
18     void print()
19     {
20         cout << "I‘m Child." << endl;
21     }
22 };
23 
24 void how_to_print(Parent* p)
25 {
26     p->print();     // 展现多态的行为
27 }
28 
29 int main()
30 {
31     Parent p;
32     Child c;
33     
34     how_to_print(&p);    // Expected to print: I‘m Parent.
35     how_to_print(&c);    // Expected to print: I‘m Child.
36     
37     return 0;
38 }

第9行加上了virtual,这就是告诉编译器,这个函数在子类中有可能被重写。得考虑是不是要展现多态的行为。

编译器在遇到virtual就会做特殊的处理。

第18行的程序没有写virtual关键字,但是由于继承的关系,它就是virtual的,这里可写可不写。

运行结果如下:

技术分享图片

 

 

多态的意义:

技术分享图片

多态在编译时无法知道要调用哪一个函数,是在运行时决定的。

但凡发生函数重写,那么被重写的函数必然的是virtual的,因为我们需要多态,要不然我们也不会重写。

理论概念:

技术分享图片

 

 动态联编与静态联编:

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 class Parent
 7 {
 8 public:
 9     virtual void func()
10     {
11         cout << "void func()" << endl;
12     }
13     
14     virtual void func(int i)
15     {
16         cout << "void func(int i) : " << i << endl;
17     }
18     
19     virtual void func(int i, int j)
20     {
21         cout << "void func(int i, int j) : " << "(" << i << ", " << j << ")" << endl;
22     }
23 };
24 
25 class Child : public Parent
26 {
27 public:
28     void func(int i, int j)
29     {
30         cout << "void func(int i, int j) : " << i + j << endl;
31     }
32     
33     void func(int i, int j, int k)
34     {
35         cout << "void func(int i, int j, int k) : " << i + j + k << endl;
36     }
37 };
38 
39 void run(Parent* p)
40 {
41     p->func(1, 2);     // 展现多态的特性
42                        // 动态联编
43 }
44 
45 
46 int main()
47 {
48     Parent p;
49     
50     p.func();         // 静态联编
51     p.func(1);        // 静态联编
52     p.func(1, 2);     // 静态联编
53     
54     cout << endl;
55     
56     Child c;
57     
58     c.func(1, 2);     // 静态联编
59     
60     cout << endl;
61     
62     run(&p);
63     run(&c);
64     
65     return 0;
66 }

同名覆盖只能发生在父类和子类之间。

运行结果如下:

技术分享图片

 

 示例程序:

 1 #include <iostream>
 2 #include <string>
 3 
 4 using namespace std;
 5 
 6 class Boss
 7 {
 8 public:
 9     int fight()
10     {
11         int ret = 10;
12         
13         cout << "Boss::fight() : " << ret << endl;
14         
15         return ret;
16     }
17 };
18 
19 class Master
20 {
21 public:
22     virtual int eightSwordKill()
23     {
24         int ret = 8;
25         
26         cout << "Master::eightSwordKill() : " << ret << endl;
27         
28         return ret;
29     }
30 };
31 
32 class NewMaster : public Master
33 {
34 public:
35     int eightSwordKill()
36     {
37         int ret = Master::eightSwordKill() * 2;
38         
39         cout << "NewMaster::eightSwordKill() : " << ret << endl;
40         
41         return ret;
42     }
43 };
44 
45 void field_pk(Master* master, Boss* boss)
46 {
47     int k = master->eightSwordKill();
48     int b = boss->fight();
49     
50     if( k < b )
51     {
52         cout << "Master is killed..." << endl;
53     }
54     else
55     {
56         cout << "Boss is killed..." << endl;
57     }
58 }
59 
60 int main()
61 {
62     Master master;
63     Boss boss;
64     
65     cout << "Master vs Boss" << endl;
66     
67     field_pk(&master, &boss);
68     
69     cout << "NewMaster vs Boss" << endl;
70     
71     NewMaster newMaster;
72     
73     field_pk(&newMaster, &boss);
74     
75     return 0;
76 }

运行结果如下:

技术分享图片

 

小结:

技术分享图片

 

以上是关于第49课 多态的概念和意义的主要内容,如果未能解决你的问题,请参考以下文章

第49课 多态的概念和意义

第56课 函数模板的概念和意义

第56课 函数模板的概念和意义

第43课 继承的概念和意义

第58课 类模板的概念和意义

第56课.函数模板的概念和意义