码迷,mamicode.com
首页 > 编程语言 > 详细

C++中虚函数的动态绑定和多态性

时间:2017-05-09 12:37:02      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:多态   size   err   color   foo   family   closed   href   参考   

目录

    • 静态类型VS动态类型,静态绑定VS动态绑定两组概念
    • 虚函数的实现机制
    • 多态性

一.静态 vs 动态

  静态类型 VS 动态类型。静态类型指的是对象声明的类型,在编译器确定的。动态类型指的是对象的所指向的类型,动态类型是可以更改的,静态类型无法更改。继承关系会导致对象的指针和引用具有静态类型和动态类型,因为继承关系的存在中可能会存在类型之间的向上向下类型转换。静态绑定 VS 动态绑定。某特性(函数)依赖与对象的静态类型,在编译期确定,某特性(函数)依赖于对象的动态类型,在运行期确定。只有通过基类的引用或者指针调用虚函数时,才能发生动态绑定,如果使用对象来操作虚函数的话,仍然会采用静态绑定的方式。因为引用或者指针既可以指向基类对象,也可以指向派生类对象的基类部分,用引用或者指针调用的虚函数例如下面的例子中,pd的静态类型是D*,pb的静态类型是B*,是在编译器确定的;pd和pb的动态类型都是D*。DoSomething()普通的成员函数是在编译器静态绑定的,调用各自的静态类型中的方法。vfun()是虚成员函数,虚函数是动态绑定的,因此调用动态类型的方法,也就是D类型中vfun。

 1 #include <iostream>
 2 using namespace std;
 3 
 4 class B
 5 {
 6 public:
 7     void DoSomething(){
 8         std::cout << "B::DoSomething()" << endl;
 9     }
10     virtual void vfun(){
11         std::cout << "B::vfun()" << endl;
12     }
13 };
14 
15 class D : public B
16 {
17 public:
18     void DoSomething(){
19         std::cout << "D::DoSomething()" << endl;
20     }
21     virtual void vfun(){
22         std::cout << "D::vfun()" << endl;
23 
24     }
25 };
26 
27 int main()
28 {
29     D* pd = new D();       //指针存在注意静态类型和动态类型
30     B* pb = pd;            //指正注意静态类型和动态类型
31     pd->DoSomething();     //普通成员函数,静态绑定静态类型中的方法
32     pb->DoSomething();     //普通成员函数,静态绑定静态类型中的方法
33
34     pd->vfun();            //虚成员函数,动态绑定到动态类型中的方法
35     pb->vfun();        //虚成员函数,动态绑定到动态类型中的方法
36     return 0;
37 }

二.虚函数的的实现机制

 

二、C++多态性

1.多态性的定义:同一操作作用于不同的对象,可以有不同的解释,即产生不同的执行效果。多态性有两种,编译时的多态,也就是函数重载;运行时多态,在系统运行时确定,是通过虚成员实现的。一般指的是后者

2.典型用例

技术分享
 1 #include <iostream>
 2 using namespace std;
 3 
 4 class Person
 5 {
 6 public:
 7     virtual void print(){
 8         std::cout << "I‘m a person" << endl;
 9     }
10    
11 };
12 
13 class Chinese : public Person
14 {
15 public:
16     virtual void print(){
17         std::cout << "I‘m as Chinese" << endl;
18     }
19    
20 };
21 
22 class American : public Person
23 {
24 public:
25     virtual void print(){
26         std::cout << "I‘m as American" << endl;
27     }
28    
29 };
30 
31 
32 //reference 
33 void printPerson(Person& person){
34     person.print();
35 }
36 //pointer 
37 void printPerson(Person* p){
38     p->print();
39 }
40 int main()
41 {
42     Person p;
43     Chinese c;
44     American a;
45     printPerson(p);
46     printPerson(c);
47     printPerson(a);
48 
49     printPerson(&p);
50     printPerson(&c);
51     printPerson(&a);
52     
53     return 0;
54 }
View Code

4.多态的实现:多态是由继承和虚函数实现的,因为虚函数是动态绑定的,依赖于调用对象(静态类型为基类的指针和引用)的动态类型,所以根据动态类型的不同,而导致操作不同,也就是多态性。

3.虚函数的实现:简单的说虚函数是通过虚函数表来实现的。

   每个带有虚函数的类,都会有一个虚函数表(vtbl),表中的每一项记录它一个的虚函数的地址。实际上一个函数指针的数组。类的对象的最前面存储虚函数表的地址。

   虚函数表在类的继承中也会继承和重写,当有重写发生时,就会产生多态性。

 1 #include <iostream>
 2 using namespace std;
 3 class Person
 4 {
 5 public:
 6     virtual void print(){
 7         std::cout << "I‘m a person" << endl;
 8     }
 9     virtual void foo(){}  
11 };
12 
13 class Chinese : public Person
14 {
15 public:
16     virtual void print(){
17         std::cout << "I‘m as Chinese" << endl;
18     }
19     virtual void foo2(){} 
20 };
21 class American : public Person
22 {
23 public:
24     virtual void print(){
25         std::cout << "I‘m as American" << endl;
26     }  
27 };
28 //reference
29 void printPerson(Person& person){
30     person.print();
31 }
32 //pointer 
33 void printPerson(Person* p){
34     p->print();
35 }
36 int main()
37 {
38     Person p;
39     Chinese c;
40     American a;
41     printPerson(&p);
42     printPerson(&c);
43     printPerson(&a);    
44     return 0;
45 }

 

Person 类的vtbl : Person::print()的地址,Person::foo()的地址

Chinese类的地址:Chinese::print()的地址,Person::foo()的地址,Person::foo1()的地址

American类的地址:American::print()的地址,Person::foo()的地址

三、总结

  多态是C++的三大特性之一,非常重要,产生的条件是继承关系,基类中存在虚成员函数,派生类override(重写覆盖)基类的的虚成员函数,在代码上表现为基类对象的指针或引用调用虚成员函数,运行结果表现为实际调用各自派生类重写的函数。

多态的核心虚成员函数是动态绑定的,即依赖于对象的动态类型。理解多态的难点是虚函数的实现机制,即虚函数表。

 

参考:http://blog.csdn.net/chgaowei/article/details/6427731

 

C++中虚函数的动态绑定和多态性

标签:多态   size   err   color   foo   family   closed   href   参考   

原文地址:http://www.cnblogs.com/wxquare/p/5017326.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!