Principle of implementing polymorphism in C language: function pointer

Source: Internet
Author: User

 
The principle of implementing polymorphism in C language: What is a function pointer? Answer: C Programming Language. You can refer to it. In principle, it is a memory address that jumps over and executes the corresponding code segment. In this case, you can jump to the desired place to execute the specific code at runtime. A simple version: uses audio decoder as an example: AAC decoder, Mpeg decoder, and other types of decoder. The manual polymorphism may be implemented as follows: 
U32 audioHandle = AudioDecOpen(int type){    if(type == aac)return aac_open();    else if(type == mpeg)        return mpeg_open();}


This code is not conducive to expansion. If you do not add a new instance, you have to change the AudioDecOpen function. And encapsulation is not good.
Another method is to write: first define the function pointers of the three public functions.
typedef int (*OpenFunc) (void *this);typedef int (*CloseFunc) (void *this);typedef int (*ControlFunc) (void *this, int command, void *param);

Define the public interface struct & AudioDecoder object:
struct module{ OpenFunc Open; CloseFunc Close; ControlFunc Control;};struct AudioDecoder{    struct module m;    int audioType;    void* private;};


A table driver is provided to help you find the corresponding entry:
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;}
In this way, when the external world creates an Audio object, the corresponding function entry has been initialized. Open is very simple:
int AudioOpen(struct AudioDecoder *dec){     return dec->m->Open(dec);}
Among them, the Private in AudioDecoder is applied for in their respective Open, released by themselves, Close, Control is similar.
You can maintain the table Driver (pool) in the future. You can add support for new objects to facilitate maintenance.
Better maintenance of the pool the current pool is still not very scalable, after all, every time you add a new object, you have to change the pool table driver. Here we provide a better method:
struct AudioPool{    int audioType;    struct module* audioModule;}pool[MAX_POOL];

Provide a function of Pool_Register (int type, struct module * module:
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;}

In this way, calling rigister in each instance can solve this problem elegantly.
The code of the two decoder objects is attached. The Mpeg decoder uses libmad, and the aac decoder uses the libfaad Library: AAC code snippet:
...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);}


MPEG code snippet:
...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);}



Conclusion: designing your own code using object-oriented methods can reduce the workload of maintenance. The MVC mode is also implemented in the C language. This part is also implemented by the function pointer, but it is actually only a callback. However, code maintenance and module division are very clear.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.