网站的优化,优秀网络小说,青岛专业制作网站的公司,淘宝放单网站怎么做的这里的例子全部来自陈皓的C 虚函数表解析#xff0c;经过修改的。 编译器#xff1a;g (Ubuntu 4.9.2-10ubuntu13) 4.9.2 环境#xff1a;ubuntu 15.04 64位系统#xff08;地址占8字节#xff09; 例子1#xff1a; 1 #define LL long long2 3 class Base {4 public:5 …这里的例子全部来自陈皓的C 虚函数表解析经过修改的。 编译器g (Ubuntu 4.9.2-10ubuntu13) 4.9.2 环境ubuntu 15.04 64位系统地址占8字节 例子1 1 #define LL long long2 3 class Base {4 public:5 virtual void f() { cout Base::f endl; }6 virtual void g() { cout Base::g endl; }7 virtual void h() { cout Base::h endl; }8 LL a; 9 };
10
11 int main(void)
12 {
13 typedef void (*Fun)(void);
14 Base b;
15 b.a10086;
16
17 Fun pFun NULL;
18
19 cout 虚函数表地址 (int*)(b) endl;
20 cout 虚函数表 — 第一个函数地址 (int*)*(int*)(b) endl;
21
22 LL *p(LL*)*(LL*)b;
23 for(int i0; i3; i)
24 {
25 pFun (Fun)*(pi);
26 pFun();
27 }
28 couta的地址 (b)1endl;
29 couta的值 *((LL*)(b)1)endl;
30 cout对象b的大小sizeof(b)endl;
31
32 return 0;
33 } 输出 解释通过强转对象b的地址将地址逐个取出来运行看看是什么。 总结对象b中存储了2个东西第一个是虚函数表指针第二个是变量a所以共计8816字节。在虚函数表指针所指的地址中有3个指针分别是3个虚函数的指针每个占8字节共计3*824字节。陈皓说虚表最后加个标志这点不知道怎么验证 验证了如下这副图 例子2 一般继承无函数覆盖的全部函数都声明为virtual 1 class Base {2 public:3 virtual void f() { cout Base::f endl; }4 virtual void g() { cout Base::g endl; }5 virtual void h() { cout Base::h endl; } 6 };7 8 class Derive:public Base{9 public:
10 virtual void f1() { cout Derive::f1 endl; }
11 virtual void g1() { cout Derive::g1 endl; }
12 virtual void h1() { cout Derive::h1 endl; }
13 };
14
15 int main(void)
16 {
17 typedef void (*Fun)(void);
18 Derive d;
19 Fun pFun NULL;
20
21 cout 虚函数表地址 (LL*)(d) endl;
22 cout 虚函数表 — 第一个函数地址 (LL*)*(LL*)(d) endl;
23
24 LL *p(LL*)*(LL*)d;
25 for(int i0; i6; i)
26 {
27 pFun (Fun)*(pi);
28 pFun();
29 }
30 cout对象d的大小sizeof(d)endl;
31
32 return 0;
33 } 输出 解释仅仅只有2个类且Derive继承Base类一共有6个虚函数。 总结对象d中一共占用8个字节也就是只保存了虚函数表的地址。虚函数表中一共有6个函数指针分别是Base的3个Derive的3个。 验证了如下这副图 例子3 一般继承只有1个函数是覆盖的全部函数都声明为virtual 1 class Base {2 public:3 virtual void f() { cout Base::f endl; }4 virtual void g() { cout Base::g endl; }5 virtual void h() { cout Base::h endl; } 6 };7 8 class Derive:public Base{9 public:
10 virtual void f() { cout Derive::f endl; }
11 virtual void g1() { cout Derive::g1 endl; }
12 virtual void h1() { cout Derive::h1 endl; }
13 };
14
15 int main(void)
16 {
17 typedef void (*Fun)(void);
18 Derive d;
19 Fun pFun NULL;
20
21 cout 虚函数表地址 (LL*)(d) endl;
22 cout 虚函数表 — 第一个函数地址 (LL*)*(LL*)(d) endl;
23
24 LL *p(LL*)*(LL*)d;
25 for(int i0; i5; i)
26 {
27 pFun (Fun)*(pi);
28 pFun();
29 }
30
31 cout对象d的大小sizeof(d)endl;
32
33 return 0;
34 } 输出 解释这个模型跟上面的差不多而这次有1个函数是覆盖的。 总结虚函数表中一共有5个函数指针Base中占2个Derive中占3个。流程是先将基类的3个函数摆在虚函数表前面接着摆派生类的由于Derive的函数f覆盖掉基类Base的函数f所以直接代替基类的函数f的位置。多态是用基类的指针指向派生类对象调用的是有覆盖的派生类中的函数。这里就可以实现多态 验证了如下这副图 例子4 多重继承无虚函数覆盖但全部函数都声明为虚函数。 1 class Base1 {2 public:3 virtual void f() { cout Base1::f endl; }4 virtual void g() { cout Base1::g endl; }5 virtual void h() { cout Base1::h endl; } 6 };7 class Base2 {8 public:9 virtual void f() { cout Base2::f endl; }
10 virtual void g() { cout Base2::g endl; }
11 virtual void h() { cout Base2::h endl; }
12 };
13 class Base3 {
14 public:
15 virtual void f() { cout Base3::f endl; }
16 virtual void g() { cout Base3::g endl; }
17 virtual void h() { cout Base3::h endl; }
18 };
19
20 class Derive:public Base1,public Base2,public Base3{
21 public:
22 virtual void f1() { cout Derive::f1 endl; }
23 virtual void g1() { cout Derive::g1 endl; }
24 };
25
26 int main(void)
27 {
28 typedef void (*Fun)(void);
29 Derive d;
30 Fun pFun NULL;
31
32 cout 虚函数表地址 (LL*)(d) endl;
33 cout 虚函数表 — 第一个函数地址 (LL*)*(LL*)(d) endl;
34
35 LL *p(LL*)*(LL*)d;
36 for(int i0; i5; i)
37 {
38 pFun (Fun)*(pi);
39 pFun();
40 }
41 for(int i0; i3; i)
42 {
43 pFun (Fun)*(pi);
44 pFun();
45 }
46 for(int i0; i3; i)
47 {
48 pFun (Fun)*(pi);
49 pFun();
50 }
51
52 cout对象d的大小sizeof(d)endl;
53
54 return 0;
55 } 输出 解释Derive类一共有3个基类按1,2,3的顺序继承。由于有3个基类所以对象d中有且仅有3个指针分别指向其基类的虚函数表。 总结虚函数表1中有5个函数虚函数表2和3中有3个函数。也就是说基类Derive中的虚函数是借放在第一个基类的虚函数表中的尾部。 验证了如下这副图 例子5 多重继承有1个虚函数覆盖全部函数声明为虚函数。 1 class Base1 {2 public:3 virtual void f() { cout Base1::f endl; }4 virtual void g() { cout Base1::g endl; }5 virtual void h() { cout Base1::h endl; } 6 };7 class Base2 {8 public:9 virtual void f() { cout Base2::f endl; }
10 virtual void g() { cout Base2::g endl; }
11 virtual void h() { cout Base2::h endl; }
12 };
13 class Base3 {
14 public:
15 virtual void f() { cout Base3::f endl; }
16 virtual void g() { cout Base3::g endl; }
17 virtual void h() { cout Base3::h endl; }
18 };
19
20 class Derive:public Base1,public Base2,public Base3{
21 public:
22 virtual void f() { cout Derive::f endl; }
23 virtual void g1() { cout Derive::g1 endl; }
24 };
25
26
27
28 int main(void)
29 {
30 typedef void (*Fun)(void);
31 Derive d;
32 Fun pFun NULL;
33
34 cout 虚函数表地址 (LL*)(d) endl;
35 cout 虚函数表 — 第一个函数地址 (LL*)*(LL*)(d) endl;
36
37 LL *p(LL*)*(LL*)d;
38 for(int i0; i4; i)
39 {
40 pFun (Fun)*(pi);
41 pFun();
42 }
43 for(int i0; i3; i)
44 {
45 pFun (Fun)*(pi);
46 pFun();
47 }
48 for(int i0; i3; i)
49 {
50 pFun (Fun)*(pi);
51 pFun();
52 }
53
54 cout对象d的大小sizeof(d)endl;
55
56 return 0;
57 } 输出 解释例子基本和上一个例子一样。基类Derive中的虚函数f 覆盖掉3个基类中的同名虚函数f。 总结依然是3个函数表只是每个函数表中的同名函数f 都被替换成了基类Derive中的函数f 。所以虚函数表1中有4个指针表2和3都分别有3个。 转载于:https://www.cnblogs.com/xcw0754/p/4973532.html