c 的抽象、封装、继承和多态几大特性当中,多态是最为重要的一个。所谓多态(这里指狭义的多态)就是父类指针或引用指向子类对象,然后可以通过父类指针或引用调用子类的成员函数。 刚开始学习多态的时候,觉得多态非常神奇,同时也非常费解。后来了解到c 的多态是通过虚函数表来实现的,但是一直也没有做一个系统的总结。今天写几个例子梳理一下c 是怎么通过虚函数表来实现多态的。
例1
#include
using namespace std;
class a {
private:
int a;
public:
virtual void f() {
cout<<"a::f()"<
定义了两个对象,b继承自a。 b重写了a的f()函数,并新增了一个虚成员函数g1()和一个普通的成员函数h()。那么对象a,b的内存布局应该如下图所示:
口说无凭,我们用gdb打印一下看看。
$ gdb a.exe
gnu gdb (gdb) 7.6.1
ag真人试玩娱乐 copyright (c) 2013 free software foundation, inc.
license gplv3 : gnu gpl version 3 or later
this is free software: you are free to change and redistribute it.
there is no warranty, to the extent permitted by law. type "show copying"
and "show warranty" for details.
this gdb was configured as "mingw32".
for bug reporting instructions, please see:
...
reading symbols from f:\zkanghust\c \a.exe...done.
(gdb) start
temporary breakpoint 1 at 0x40146e: file test3.cpp, line 32.
starting program: f:\zkanghust\c /a.exe
[new thread 10860.0x2e0c]
[new thread 10860.0x3e64]
[new thread 10860.0x3e94]
[new thread 10860.0x8]
temporary breakpoint 1, main () at test3.cpp:32
32 a a;
(gdb) n
33 b b;
(gdb)
51 return 0;
(gdb) p a
$1 = {_vptr.a = 0x405178 , a = 4194432}
(gdb) p (int*)*((int*)0x405178)
$2 = (int *) 0x403c08
(gdb) p (int*)*((int*)0x405178 1)
$3 = (int *) 0x403c3c
(gdb) p (int*)*((int*)0x405178 2)
$4 = (int *) 0x0
(gdb) p b
$5 = {