C 语言实现多态的原理:函数指针
C语言实现多态的原理:函数指针
一个简单的版本号:
U32 audioHandle = AudioDecOpen(int type)
{
if(type == aac)
return aac_open();
else if(type == mpeg)
return mpeg_open();
}
第二种方法来写:
typedef int (*OpenFunc) (void *this);
typedef int (*CloseFunc) (void *this);
typedef int (*ControlFunc) (void *this, int command, void *param);
AudioDecoder 对象:
struct module
{ OpenFunc Open; CloseFunc Close; ControlFunc Control;};
struct AudioDecoder{
struct module m;
int audioType;
void* private;
};
struct AudioPool{
int audioType;
struct module* audioModule;
}pool[] = {
{aac , aac_module},
{mpeg , mpeg_module},
};
int AudioCreate(int type , Handle *handle)
{
AudioDecoder dec = alloc_audioDec();
foreach(pool , k)
{
if(k->audioType == type)
{
dec->m = k->audioModule;
}
}
*handle = (Handle)dec;
}
这样,当外界去Create一个Audio的对象时,就已经初始化好相应的函数入口了。Open就非常easy了:
int AudioOpen(struct AudioDecoder *dec)
{
return dec->m->Open(dec);
}
当中AudioDecoder中的Private 则是在各自的Open中自己申请,自己释放,Close,Control 相似。
更好的维护pool
struct AudioPool{
int audioType;
struct module* audioModule;
}pool[MAX_POOL];
int Pool_Register(int type , struct module* module);
{
for_each(pool , k)
{
if(k->type == INVALID_AUDIO_TYPE)
{
k->type = type;
k->audioModule = module;
}
}
if(k == NULL)
{
return REACH_POOL_END;
}
return NO_ERROR;
}
这样在每一个实例中调用 rigister 就能够非常优雅的解决问题。
.
.
.
static int Close(void *this)
{
AudioSoftDecoder *ad = (AudioSoftDecoder*)this;
if(!ad || !ad->privateData)
{
syslog(LOG_ERR , "%s(%d):Bad Parameter !!!\n" , __FUNCTION__ , __LINE__ );
return CT_ERROR_BAD_PARAMETER;
}
AacFaadPrivate *private = (AacFaadPrivate *)ad->privateData;
private->exit = TRUE;
if(private->decoderPid > 0)
{
pthread_join(private->decoderPid , NULL);
}
if(private->hDecoder)
{
NeAACDecClose(private->hDecoder);
}
free(private);
ad->privateData = NULL;
return CT_ERROR_NO_ERROR;
}
int AAC_Init()
{
return RegisterAudioSoftDec(AudioDecType_AAC ,&aacModule);
}
.
.
.
int Close(void *this)
{
AudioSoftDecoder *ad = (AudioSoftDecoder*)this;
if(!ad || !ad->privateData)
{
syslog(LOG_ERR , "%s(%d):Bad Parameter !!!\n" , __FUNCTION__ , __LINE__ );
return CT_ERROR_BAD_PARAMETER;
}
mpegMadPrivate *private = (mpegMadPrivate *)ad->privateData;
private->exit = TRUE;
if(private->decoderPid > 0)
{
pthread_join(private->decoderPid , NULL);
}
mad_decoder_finish(&private->decoder);
if(private->data.buffer)
{
free(private->data.buffer);
}
free(private);
ad->privateData = NULL;
return CT_ERROR_NO_ERROR;
}
int Control(void *this , U32 cmd ,void* param)
{
return CT_ERROR_NO_ERROR;
}
int MPEG_Init()
{
return RegisterAudioSoftDec(AudioDecType_MPEG ,&mpegModule);
}
总结:
在C语言里面还实现了MVC模式等,这部分也是函数指针实现的。实际上仅仅是一个回调。
可是代码维护,模块划分上,非常清晰。
C 语言实现多态的原理:函数指针的更多相关文章
- C语言结构体中的函数指针
这篇文章简单的叙述一下函数指针在结构体中的应用,为后面的一系列文章打下基础 本文地址:http://www.cnblogs.com/archimedes/p/function-pointer-in ...
- 【嵌入式开发】C语言 结构体相关 的 函数 指针 数组
. 作者 : 万境绝尘 转载请注明出处 : http://www.hanshuliang.com/?post=30 . 结构体概述 : 结构体是 多个 变量的集合, 变量的类型可以不同; -- 可进行 ...
- 复习C语言系列二:动态调用函数指针数组
a:用call_fun_ptr调用afun(),b:用call_fun_ptr调用bfun() a 请输入给您指定的函数输调用的参数 afun_par ------------------------ ...
- C语言复杂的函数指针声明
复习C语言ING,发现复杂的函数指针声明看不懂,百度半天终于略知一二. 讲的比较详细的一篇blog: http://blog.csdn.net/megaboy/article/details/4827 ...
- Day8 函数指针做函数参数
课堂笔记 课程回顾 多态 virtual关键字 纯虚函数 virtual func() = 0; 提前布局vptr指针 面向接口编程 延迟绑定 多态的析构函数的虚函数. ...
- C++ 类的多态三(多态的原理--虚函数指针--子类虚函数指针初始化)
//多态的原理--虚函数指针--子类虚函数指针初始化 #include<iostream> using namespace std; /* 多态的实现原理(有自己猜想部分) 基础知识: 类 ...
- c++语言虚函数实现多态的原理(更新版)
自上一个帖子之间跳过了一篇总结性的帖子,之后再发,今天主要研究了c++语言当中虚函数对多态的实现,感叹于c++设计者的精妙绝伦 c++中虚函数表的作用主要是实现了多态的机制.首先先解释一下多态的概念, ...
- 2014 0416 word清楚项目黑点 输入矩阵 普通继承和虚继承 函数指针实现多态 强弱类型语言
1.word 如何清除项目黑点 选中文字区域,选择开始->样式->全部清除 2.公式编辑器输入矩阵 先输入方括号,接着选择格式->中间对齐,然后点下面红色框里的东西,组后输入数据 ...
- Atitit java方法引用(Method References) 与c#委托与脚本语言js的函数指针
Atitit java方法引用(Method References) 与c#委托与脚本语言js的函数指针 1.1. java方法引用(Method References) 与c#委托与脚本语言js ...
随机推荐
- Java生成二维码和解析二维码URL
二维码依赖jar包,zxing <!-- 二维码依赖 start --><dependency> <groupId>com.google.zxing</gro ...
- linux设置别名
1.查看别名: alias 2.临时设置别名 alias show='ls -al' 3.永久生效 vi 家目录/.bashrc alias mmm='mysql -uroot -p' 4.删除别名 ...
- 宏定义中的反斜杠"\"和宏定义的细节说明
转载自:http://www.wtoutiao.com/p/K6csca.html 在阅读C语言代码经常可以看到代码中出现反斜杠"\",不是很明白它的意思,遂对反斜杠"\ ...
- 一个最简单的LRUCache实现 (JAVA)
流程图: 1. 代码 import java.util.ArrayList; public class LRUCache { private int cacheMaxSize = 0; private ...
- go get 下载需要的相关工具
文档来源: https://code.google.com/p/go-wiki/wiki/GoGetTools 被墙了,所以转在这个备用. Installing Version Control Too ...
- spring实现可重置时间定时器
此文章是基于 搭建Jquery+SpringMVC+Spring+Hibernate+MySQL平台 一. jar包介绍 1. spring-framework-4.3.4.RELEASE 的 lib ...
- 结构型--代理模式(Proxy)
一.代理模式是什么? 代理模式属于GOF23设计模式中结构型中的设计模式,通过代理对象来屏蔽(部分或者屏蔽)对真实对象的直接访问,下图为UML图: 在代理模式中组件包括:抽象角色接口.代理角色类.真实 ...
- Java并发—–深入分析synchronized的实现原理
记得刚刚开始学习Java的时候,一遇到多线程情况就是synchronized,相对于当时的我们来说synchronized是这么的神奇而又强大,那个时候我们赋予它一个名字“同步”,也成为了我们解决多线 ...
- 如何将一个SpringBoot简便地打成一个war包(转)
为什么要把SpringBoot打成war包 正常情况下SpringBoot项目是以jar包的形式,通过命令行: java -jar demo.jar 来运行的,并且SpringBoot是内嵌Tomca ...
- 原生JS,运动的小人
今天突然想起来,不知道在什么网站上看的一个纯纯的原生JS写的效果,运动的小人,所以在这里给大家分享一下代码: 并说明:这不是本人写的,而是我在浏览网站是无意中发现的,现在已经不记得是哪个网站了,但是要 ...