本文参考以下作者文章文章
来自:吴秦 - 博客园
作者:吴秦
链接:http://www.cnblogs.com/skynet/archive/2010/09/23/1833217.html
继承和多态是面向对象语言最强大的功能。有了继承和多态,我们可以完成代码重用。在C中有许多技巧可以实现多态。本文的目的就是演示一种简单和容易的技术,在C中应用继承和多态。通过创建一个VTable(virtual table)和在基类和派生类对象之间提供正确的访问,我们能在C中实现继承和多态。VTable能通过维护一张函数表指针表来实现。为了提供基类和派生类对象之间的访问,我们可以在基类中维护派生类的引用和在派生类中维护基类的引用
在C中实现继承和多态之前,我们应该知道类(Class)在C中如何表示。
代码如下
//person.h
#ifndef PERSON_H
#define PERSON_H
typedef struct _Person Person;
typedef void (*fptrDisplayInfo)(Person*);
typedef void (*fptrWriteToFile)(Person*);
typedef void (*fptrDelete)(Person*);
typedef struct _Person
{
void* pDerivedObj;//指向派生类
char* pFirstName;
char* pLastName;
fptrDisplayInfo DisplayInfo;
fptrWriteToFile WriteToFile;
fptrDelete Delete;
}Person;
Person* new_Person(const char* const pFirstName, const char* const pLastName);
void delete_Person(Person* const pPersonObj);
void Person_DisplayInfo(Person* const pPersonObj);
void Person_WriteToFile(Person* const pPersonObj, const char* const pFileName);
#endif // PERSON_H
//person.c
#include"person.h"
#include"stdio.h"
Person* new_Person(const char* const pFirstName, const char* const pLastName)
{
Person* pObj = NULL;
//allocating memory
pObj = (Person*)malloc(sizeof(Person));
if (pObj == NULL)
{
return NULL;
}
pObj->pDerivedObj = pObj;//指向自己
pObj->pFirstName = malloc(sizeof(char)*(strlen(pFirstName)+1));
if (pObj->pFirstName == NULL)
{
return NULL;
}
strcpy(pObj->pFirstName, pFirstName);
pObj->pLastName = malloc(sizeof(char)*(strlen(pLastName)+1));
if (pObj->pLastName == NULL)
{
return NULL;
}
strcpy(pObj->pLastName, pLastName);
//Initializing interface for access to functions
pObj->Delete = delete_Person;
pObj->DisplayInfo = Person_DisplayInfo;
pObj->WriteToFile = Person_WriteToFile;
return pObj;
}
void delete_Person(Person* const pPersonObj)
{
}
void Person_DisplayInfo(Person* const pPersonObj)
{
}
void Person_WriteToFile(Person* const pPersonObj, const char* const pFileName)
{
}
//employee.h
#ifndef EMPLOYEE_H
#define EMPLOYEE_H
#include "person.h"
typedef struct _Employee Employee;
typedef struct _Employee
{
Person* pBaseObj;//指向基类
char* pDepartment;
char* pCompany;
int nSalary;
}Employee;
Person* new_Employee(const char* const pFirstName, const char* const pLastName,
const char* const pDepartment, const char* const pCompany, int nSalary);
void delete_Employee(Person* const pPersonObj);
void Employee_DisplayInfo(Person* const pPersonObj);
void Employee_WriteToFile(Person* const pPersonObj,const char* const pFileName);
#endif // EMPLOYEE_H
//employee.c
#include"employee.h"
#include<stdio.h>
Person* new_Employee(const char* const pFirstName, const char* const pLastName,
const char* const pDepartment, const char* const pCompany, int nSalary)
{
Employee* pEmpObj;
//calling base class construtor
Person* pObj = new_Person(pFirstName, pLastName);
//allocating memory
pEmpObj = malloc(sizeof(Employee));
if (pEmpObj == NULL)
{
pObj->Delete(pObj);
return NULL;
}
pObj->pDerivedObj = pEmpObj; //pointing to derived object
pEmpObj->pBaseObj = pObj;
//initialising derived class members
pEmpObj->pDepartment = malloc(sizeof(char)*(strlen(pDepartment)+1));
if(pEmpObj->pDepartment == NULL)
{
return NULL;
}
strcpy(pEmpObj->pDepartment, pDepartment);
pEmpObj->pCompany = malloc(sizeof(char)*(strlen(pCompany)+1));
if(pEmpObj->pCompany== NULL)
{
return NULL;
}
strcpy(pEmpObj->pCompany, pCompany);
pEmpObj->nSalary = nSalary;
//Changing base class interface to access derived class functions
//virtual destructor
//person destructor pointing to destrutor of employee
pObj->Delete = delete_Employee;
pObj->DisplayInfo = Employee_DisplayInfo;
pObj->WriteToFile = Employee_WriteToFile;
return pObj;
}
void delete_Employee(Person* const pPersonObj)
{
}
void Employee_DisplayInfo(Person* const pPersonObj)
{
}
void Employee_WriteToFile(Person* const pPersonObj,const char* const pFileName)
{
}
//main.c
#include <stdio.h>
#include "employee.h"
int main(int argc, char *argv[])
{
Person* PersonObj = new_Person("Anjali", "Jaiswal");
Employee* EmployeeObj = new_Employee("Gauri", "Jaiswal","HR", "TCS", 40000);
//accessing person object
//displaying person info
PersonObj->DisplayInfo(PersonObj);
//writing person info in the persondata.txt file
// PersonObj->WriteToFile(PersonObj,"persondata.txt");
//calling destructor
PersonObj->Delete(PersonObj);
//accessing to employee object
//displaying employee info
//通过基类调用基类函数指针指向的派生类的函数
EmployeeObj->pBaseObj->DisplayInfo(EmployeeObj);
//writing empolyee info in the employeedata.txt file
// EmployeeObj->WriteToFile(EmployeeObj, "employeedata.txt");
//calling destrutor
EmployeeObj->pBaseObj->Delete(EmployeeObj);
printf("%d",EmployeeObj->nSalary);
return 0;
}
结论
使用上面描述的简单的额外代码能是过程式C语言有多态和继承的特性。我们简单的使用函数指针创建一个VTable和在基类和派生类对象中交叉维护引用。用这些简单的步骤,我们在C中可以实现继承和多态。