稍微修改:http://blog.csdn.net/viper/article/details/6616141
中代码:变量的名字改成了自己喜欢的,更有力与自己的理解!
<pre name="code" class="cpp">#include<stdio.h>
#include<iostream>
using namespace std;
// 几个基本的函数,对应抽象类中的虚函数
//
void foo1()
{
printf( "Base foo1 \r\n" );
}
void foo2( int i )
{
}
void foo3( int i, int j )
{
}
// 虚表,包含了虚函数的指针
typedef struct Vtbl
{
void (*pf1)();
void (*pf2)( int );
void (*pf3)( int, int );
}Vtbl;
// 类的虚表
Vtbl g_vtbl = { &foo1, &foo2, &foo3};
// 基类,开始处是虚表指针,
// 后面是结构成员。
typedef struct Base
{
Vtbl *pvtbl;
// void *pvtbl;
int field1;
int field2;
}Base;
// 构造函数
// 也是一个普通的成员函数,需要一个this指针
void InitBase( Base *p )
{
p->pvtbl = &g_vtbl;
p->field1 = 0x1234;
p->field2 = 0x5678;
}
// 子类中的虚函数,重载了父类中的同类型函数
void Sfoo1()
{
// 可以考虑调用父类中的函数
// foo1();
printf( "Derived foo1 \r\n" );
}
void Sfoo4( char *s )
{
printf( "hello %s\r\n", s );
}
// 子类中的虚表,因为内存布局是一样的,
// 直接使用父类的
typedef struct SVtbl
{
Vtbl vtbl;
void (*pf4)( char * );
}SVtbl;
// 子类的虚表
SVtbl g_svtbl = { { &Sfoo1, &foo2, &foo3}, &Sfoo4 };
// 某个子类,包含父类的内容
// 还有自己的成员
typedef struct Derived
{
Base a;
int field3;
}Derived;
// 构造函数
// 也是一个普通的成员函数,需要一个this指针
void InitDerived( Derived *p )
{
InitBase( (Base*)p );//先调用父类的构造函数
p->a.pvtbl = (Vtbl*)&g_svtbl;//这里要注意,多态就是这个地方的绑定了虚函数表,
p->field3 = 0xabcd;
}
void TestPolymorphism( Base *p )
{
// 虽然使用的是父类型的指针
// 但虚函数最终会根据对象的真实类型调用。
(*((Vtbl*)p->pvtbl)->pf1)();
}
void TestVtbl()
{
// 子类的一个对象
Derived s;
Base *p = 0;
// 初始化
InitDerived( &s );
p = (Base*)&s;
// 调用Sfoo4
((SVtbl*)p->pvtbl)->pf4( "Sfoo4" );
// 测试多态
TestPolymorphism( (Base*)&s );
}
void main()
{
/*Base* p;
Base b;
InitBase(&b);
p=&b;
TestPolymorphism(p);
Derived d;
InitDerived(&d);
p=(Base*)&d;
TestPolymorphism(p);*/
TestVtbl();
}