【C语言】C语言实现面向对象编程之多态

00. 目录

01. 概述

在C语言中还可以实现更深入的面向对象编程多态特性。例如:使用接口(interface)包含多个指向函数的指针,这样就可以实现操作的"多态性"。

在面向对象语言C++的实现上,使用了虚函数的方式,虚函数实质上也是指向虚表(virtual table)的一个函数指针。C++虚表方式的本质和包含的各个函数指针的操作数据结构类似。

02. C语言基于对象编程实现部分多态功能

test.h文件内容如下:

#ifndef __TEST_H__
#define __TEST_H__

#ifdef __cplusplus
//表示是C语言的头文件
extern "C"
{
#endif

typedef void * HPERSON;

//创建对象
HPERSON createPerson(const char *name);

//显示对象
void displayPerson(HPERSON person);

//删除对象
void deletePerson(HPERSON person);




//-----------------STUDENT-----------------
typedef void* HSTUDENT;

//创建对象
HSTUDENT createStudent(const char *name, int age, int id, int score);


//删除对象
void deleteStudent(HSTUDENT student);

#ifdef __cplusplus
}
#endif

#endif /*__TEST_H__*/

test.c具体实现如下:

#define _CRT_SECURE_NO_WARNINGS
#include "test.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

//函数指针
typedef struct _PersonOps
{
	void (*display)(HPERSON);
}PersonOps;

//Person表示HPERSON句柄指向的结构体
typedef struct _Person 
{
	//使用指针
	char *name;
	int age;
	int id;

	PersonOps* ops;
}Person;

//显示对象
static void do_displayPerson(HPERSON person)
{
	Person* p = person;
	if (NULL == p)
	{
		printf("displayPerson 参数非法\n");
		return;
	}

	printf("Name: %s age: %d id:%d\n", p->name, p->age, p->id);
}

static PersonOps opsPerson = {
	do_displayPerson
};

//创建对象
HPERSON createPerson(const char * name)
{
	Person *p = NULL;

	printf("创建对象\n");


	p = malloc(sizeof(Person));
	if (NULL == p)
	{
		printf("分配内存失败\n");
		return NULL;
	}
	memset(p, 0, sizeof(Person));

	p->name = malloc(strlen(name) + 1);
	if (NULL == p->name)
	{
		printf("分配内存失败\n");
		return NULL;
	}

	strcpy(p->name, name);
	p->age = 0;
	p->id = 0;
	p->ops = &opsPerson;
	
	return p;
}

//显示对象
void displayPerson(HPERSON person)
{
	Person* p = person;

	p->ops->display(person);
}




//删除对象
void deletePerson(HPERSON person)
{
	Person *p = person;

	if (NULL == person)
	{
		return;
	}

	if (NULL != p->name)
	{
		free(p->name);
	}

	free(person);
}


//---------------------STUDENT--------------------

typedef struct _stu_t {
	Person person;
	int score;
}Student;

static void do_displayStudent(HSTUDENT student)
{
	Student* s = student;

	if (NULL == student)
	{
		return;
	}

	do_displayPerson(&(s->person));
	printf("score: %d\n", s->score);
}

static PersonOps opsStudent = {  
	do_displayStudent
};

//创建对象
HSTUDENT createStudent(const char* name, int age, int id, int score)
{
	Student *s = malloc(sizeof(Student));
	if (NULL == s)
	{
		return NULL;
	}
	memset(s, 0, sizeof(Student));

	s->person.name = malloc(strlen(name) + 1);
	if (NULL == s->person.name)
	{
		return;
	}
	memset(s->person.name, 0, strlen(name) + 1);

	strcpy(s->person.name, name);
	s->person.age = age;
	s->person.id = id;
	s->score = score;

	s->person.ops = &opsStudent;
	return s;
}

//删除对象
void deleteStudent(HSTUDENT student)
{
	Student *s = student;

	if (NULL == s)
	{
		return;
	}

	if (NULL != s->person.name)
	{
		free(s->person.name);
	}
	free(s);


}

main.c实现如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "test.h"

//主函数
int main()
{

	HSTUDENT s = createStudent("李明", 12, 1, 99);

	displayPerson(s);
	deleteStudent(s);

	system("pause");
	return 0;
}

测试结果如下:

Name: 李明 age: 12 id:1
score: 99
请按任意键继续. . .

03. 总结

在本例中,含有不同操作的结构体内存格式如下所示
在这里插入图片描述

PersonOpt数据结构是一个表示"对象"操作的函数表。该程序中它包含了一个操作函数(函数指针)display。在实际应用中,这种函数表数据结构还可能包含更多的数据结构。

总之,利用操作的函数指针列表可以实现部分“多态”功能,其本质是对于不同类型的数据结构调用不同的实现函数。

04. 下载

4.1 代码下载:C语言实现对象编程之多态代码.rar

05. 附录

猜你喜欢

转载自blog.csdn.net/dengjin20104042056/article/details/106780198
今日推荐