如果一个类中存在虚函数,在声明类的对象时,编译器就会给该对象生成一个虚函数指针,该虚函数指针指向该类对应的虚函数表。
多态的实现是因为使用了一种动态绑定的机制,在编译期间不确定调用函数的地址,在调用虚函数的时候,去查询虚函数指针所指向的虚函数表。
派生类生成的对象中的虚函数指针指向的是派生类的虚函数表,因此无论是基类还是派生来调用,都是查询的是派生类的表,调用的是派生类的函数。
如果发生了多继承,多个基类中都有虚函数,那么该是怎样的呢?虚函数指针如何排列,多个基类的指针为什么能够同时指向派生类对象,同时发生多态?
请看下面这段程序
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
#include <stdio.h>
#include <iostream>
using namespace std;
class Base1{
public :
void fun()
{
printf ( "this is Base1 fun\n" );
}
virtual void fun1()
{
printf ( "this is Base1 fun1\n" );
}
};
class Base2{
public :
void fun()
{
printf ( "this is Base2 fun\n" );
}
virtual void fun2()
{
printf ( "this is Base2 fun1\n" );
}
};
class Derived : public Base1, public Base2{
public :
void fun()
{
printf ( "this is Derived fun\n" );
}
void fun1()
{
printf ( "this is Derived fun1\n" );
}
void fun2()
{
printf ( "this is Derived fun2\n" );
}
};
int main()
{
Derived *pd = new Derived();
Base1 *p1 = (Base1 *)pd;
Base2 *p2 = (Base2 *)pd;
p1->fun();
p2->fun();
p1->fun1();
p2->fun2();
printf ( "Base1 p1:%x\n" , p1);
printf ( "Base2 p2:%x\n" , p2);
return 0;
}
|
运行结果如下
1
2
3
4
5
6
7
8
|
feng@mint ~/code/c++/cpp_muti_drived
$ ./muti_derived
this is Base1 fun
this is Base2 fun
this is Derived fun1
this is Derived fun2
Base1 p1:2097c20
Base2 p2:2097c28
|
Derived类分别继承了Base1和Base2,根据结果来看,均发生了多态。基类指针调用函数,调用的均是派生类的对象。
通过打印出了p1和p2的地址,发现他们相差了8个字节,就能明白了,在做类型转换的过程中,如果把地址传给第二个基类的指针的时候会自动把地址减去8,在64位系统下,刚好是一个指针的长度。因此p2指向的实际上是第二个虚函数指针的地址,这样,就能够实现多继承的多态了。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
原文链接:http://www.cnblogs.com/0x12345678/p/6987838.html