C模拟实现C++多态

稍微修改: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();
}



                
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值