如下一段C++代码,翻译成为C++代码,实现虚函数展现多态性的原理

 

class Base {
         int data;
 public:
         Base() : data(3) {}
         virtual int getData() const {
                 return data;
         }
 };

 class Circle:public Base {
         int data;
 public:
         Circle() : data(5) {}
         int getData() const {
                 return data;
         }
 };

 

分析:

c++虚函数实现多态的原理是:C++编译器为每个含虚函数的类提供一个虚表(虚拟继承形成的虚类表暂不讨论),虚表用来记录虚函数的地址,即虚表中的的指针指向虚函数的地址。当子类继承父类时,子类重写父类虚函数,虚表中的虚函数地址会更新为子类中的虚函数地址,虚表指针指向子类虚函数,通过父类指针调用子类重写的虚函数时,以此实现多态。

 

利用结构体和函数指针,可以用C实现C++的虚函数的多态性。

上面代码用C翻译如下:

 

#include<stdio.h>
#include<stdlib.h>
#define TRUE 1
#define FALSE 0
typedef void (*VirtualFunPointer)(...);//虚函数指针
typedef int BOOLEAN;

 /**
 构造虚表的结构体
 **/
struct VTable
{
 //通过函数指针,实现虚函数调用 

VirtualFunPointer pFunc};

/**
类base对应的c++代码
**/
struct Base
{
 int data;
 //多态机制时,c++插入一个虚表,里面记录虚函数被调用的入口地址,只要基类有
 //虚函数,则虚表指针应该被加入
 VTable *pVTable;
};
Base *Base_Constructor(Base *this_ptr,int data);//基类里面的构造函数
int Base_getData(Base *this_ptr);//基类里面的虚函数
void Base_Destructor(Base *this_ptr,BOOLEAN dynamic);//基类里面的虚拟函数

//记录基类中虚函数的入口地址
VTable VTableArrayForBase[]=
{
 (VirtualFunPointer)Base_getData,
 (VirtualFunPointer)Base_Destructor
}; 

//基类中的方法实现
int Base_getData(Base *this_ptr)
{
 printf("调用的是Base_getData方法\n");
 return this_ptr->data;
}

 

//构造函数

Base *Base_Constructor(Base *this_ptr,int data)
{
 if(this_ptr==NULL)
 {
  this_ptr=(Base*)malloc(sizeof(Base));
 }

 if(this_ptr)
 {
  this_ptr->pVTable=VTableArrayForBase;//构造方法中进行虚表创建和虚表指针初始化
  this_ptr->data=data;
 }
 return this_ptr;
}

//析构函数

void Base_Destructor(Base *this_ptr,BOOLEAN dynamic)
{
 this_ptr->pVTable=VTableArrayForBase;
 if(dynamic)
 {
  free(this_ptr);
 }
}

//子类  

struct Circle
{
 int data;
 VTable *pVTable;//每一个含虚函数的类都会有一个虚表
};

Circle *Circle_Constructor(Circle *this_ptr,int data);//子类构造方法
int Circle_getData(Circle *this_ptr);//重写虚函数
void Circle_Destructor(Circle *this_ptr,BOOLEAN dynamic);//析构

 

//虚表

VTable VTableArrayForCircle[]=
{
 (VirtualFunPointer)Circle_getData,
 (VirtualFunPointer)Circle_Destructor
};

 

Circle *Circle_Constructor(Circle *this_ptr,int data)
{
 if(this_ptr==NULL)
 {
  this_ptr=(Circle *)malloc(sizeof(Circle));
 }

 if(this_ptr)
 {
  //继承,先调用父类构造函数
  Base_Constructor((Base*)this_ptr,data);
  this_ptr->pVTable=VTableArrayForCircle;//更新虚表中的虚表函数地址
 }
 return this_ptr;
}

void Circle_Destructor(Circle *this_ptr,BOOLEAN dynamic)
{
 this_ptr->pVTable=VTableArrayForCircle;
 Base_Destructor((Base *)this_ptr,FALSE);
 if(dynamic)
 {
  free(this_ptr);
 }
}

int Circle_getData(Circle *this_ptr)
{
 printf("调用的是Circle_getData方法\n");
 return this_ptr->data;
}

 

 int main(int argc,char* argv[])
 {
  Base *pBase=(Base *)Circle_Constructor(NULL,3);//
  Circle aCircle;
  Circle_Constructor(&aCircle,5);
  printf("pBase->data:%d\n",pBase->data);
  (pBase->pVTable->pFunc)(pBase,TRUE);
  int a=Circle_getData(&aCircle);
  printf("a is %d\n",a);
  Circle_Destructor(&aCircle,FALSE);
   return 0;
 }

 

运行结果:

pBase->data:3

调用的是Circle_getData方法