C Language Polymorphism Implementation example

Source: Internet
Author: User
Tags assert cas constructor switch case


These design patterns are based on abstract classes. The use of abstract objects is a core here.

In fact, I think one of the core problems of frame programming is abstraction, which is the general idea of object-oriented programming, which uses abstract object to build the main frame of program. Building a skeleton with abstraction, plus polymorphism, forms a complete program. Because the C + + language itself implements inheritance and polymorphism, use this programming philosophy (what does the idea mean?) With a wind, hehe) in C + + is very common phenomenon, can be said virtual (polymorphic) is the soul of VC.

However, we all use the C language to forget this polymorphism. I often hear the elder say, class? Multi-state? We're using C, let's just forget about it. Unfortunately, I am a stubborn person. Such a good thing, why not use it. Very happy, in some of the most recent pure C code, I saw the polymorphism in C! Below and listen to me slowly.

1. What is the interface in VC

Interface: The Chinese explanation is the interface, in fact it represents a pure virtual class. But what I want to say is that in VC interface is actually suct, look for the definition of interface, you can find that there is such a macro definition:

#Ifndef Interface

#define Interface Suct

#endif

And, actually in VC, if a class has virtual function, then the class will have V, which is actually a list of virtual functions. In fact, C + + is from the development of, it is only at the language level to support a lot of new features, in the C language, we can also use such a function, if we have to implement ourselves.

2. How to implement a pure virtual class in C (I call it a pure virtual structure)

Compare the front, I believe we have been enlightened. Pure virtual classes can be implemented using SUCT combination function pointers.

Example:

typedef suct {

void (*FOO1) ();

char (*FOO2) ();

Char* (*foo3) (char* St);

}

Myvirtualinterface;

This assumes that we want to use the bridge pattern in the main frame. (Our main class is domyact, interface specific implementation class is ACT1,ACT2) below I will introduce these "classes" in turn. (C in the "class" in the previous note, here a change, is the use of early array method)

Main class Domyact: The main class contains myvirtualinterface* m_pinterface; The main class has the following function:

Domyact_setinterface (myvirtualinterface* pinterface)

{

M_pinterface= Pinterface;

}

Domyact_do ()

{

if (m_pinterface==null) return;

M_pinterface->foo1 ();

C=m_pinterface->foo2 ();

}

Subclass Act1: Realize virtual structure, contain myvirtualinterface St[max]; There are the following functions:

myvirtualinterface* Act1_creatinterface ()

{

Index=findvalid ()///object pool or use malloc! Should stay outside to apply, instantiate

if (index==-1) return NULL;

St[index]. Foo1=act1_foo1; Act1_foo1 to be implemented in the following detail

St[index]. Foo2=act1_foo2;

St[index]. Foo3=act1_foo3;

return &st [index];

}

Sub-class Act2 ibid.

In main, suppose you have an object list. The myvirtualinterface pointer is stored in the list, and there are:

if ((p= act1_creatinterface ())!= NULL)

List_addobject (&list, p); ADD All

while (P=list_getobject ()) {

Domyact_setinterface (P);//use interface instead of the original Big Switch case

DOMYACT_DO ()//Ignore specific actions, just do it

}

Free All

Writer, for example, you can use a macro definition as follows:

1.TXTWRITER.H/.C defines and implements Txt_writer_open,txt_writer_write,txt_writer_close three functions respectively, binwriter.h/.c define and implement Bin_writer_ Open,bin_writer_write,bin_writer_close three functions;

2. The definition header file Writer.h is as follows (only the main part):

#define TXT_MODE 1

#define BIN_MODE 2

#define Writer_mode Txt_mode

#if Writer_mode==txtmode

#include "TxtWriter.h"

#define Writer_open Txt_writer_open

#define Writer_write Txt_writer_write

#define Writer_close Txt_writer_close

#elif Writer_mode==bin_mode

#include "BinWriter.h"

#define Writer_open Bin_writer_open

#define Writer_write Bin_writer_write

#define Writer_close Bin_writer_close

#endif

Thus, in the specific use of the introduction of Writer.h header files and through the Writer_open, Writer_write, writer_close call the corresponding function, and change the Writer_mode and recompile, you can achieve the corresponding output mode switching.

Now we're going to do it. C language Inheritance and polymorphism, we still take a more classic animal world examples to illustrate: Suppose the animals (including people) would eat (Eat), would go (Walk), would say (Talk), and the derived classes were dog (doggy) and Cat (cats), and of course could be more , dog and cat have their own unique eat, walk, and talk, and the approximate code is as follows:

Base class Code Animal-base.h|c:


/*
* =============================================================================
*
* Filename:animal-base.h
*
* Description:animal base class.
*
* created:12/31/2012 11:36:43 AM
*
* Author:fu haiping (forhappy), haipingf@gmail.com
* Company:ict (Institute of Computing Technology, CAS)
*
* =============================================================================
*/
#ifndef _animal_h_
#define _animal_h_

typedef struct ANIMAL_S_ animal_t;
typedef struct ANIMAL_OPS_S_ animal_ops_t;


/* Animal, is the base class of all animals, is also abstract class * *
struct Animal_s_ {
Char *name; The name of the/*< animal * *
animal_ops_t *animal_ops; * The basic behavior of animals * *
};

* The basic behavior of animals * *
struct Animal_ops_s_ {
* * What food the animals eat/
void (*eat) (char *food);
* * How many steps did the animal walk?
void (*walk) (int steps);
* * What the animal is saying * *
void (*talk) (char *msg);
};

/* The constructor of the base class, which needs to display the call * *
extern animal_t * Animal_init (char *name);

/* Base class related operations, such as eating, walking, saying and so on * *
extern void Animal_eat (animal_t *animal, char *food);
extern void Animal_walk (animal_t *animal, int steps);
extern void Animal_talk (animal_t *animal, char *msg);

/* The destructor of the base class, need to display the call * *
extern void Animal_die (animal_t *animal);

#endif/* _animal_h_ * *

/*
* =============================================================================
*
* FILENAME:ANIMAL-BASE.C
*
* Description:animal base class.
*
* created:12/31/2012 12:27:27 PM
*
* Author:fu haiping (forhappy), haipingf@gmail.com
* Company:ict (Institute of Computing Technology, CAS)
*
* =============================================================================
*/
#include <assert.h>
#include <stdlib.h>
#include <string.h>

#include "animal-base.h"

/* The constructor of the base class, which needs to display the call * *
animal_t * Animal_init (char *name)
{
ASSERT (name!= NULL);
size_t Name_len = strlen (name);

animal_t *animal = (animal_t *) malloc (sizeof (animal_t)
+ sizeof (animal_ops_t) + Name_len + 1);
memset (animal, 0, sizeof (animal_t) + sizeof (animal_ops_t)
+ Name_len + 1));
Animal->name = (char *) animal + sizeof (animal_t);
memcpy (animal, name, Name_len);
Animal->animal_ops = (animal_ops_t *) ((char *) animal
+ sizeof (animal_t) + Name_len + 1);

return animal;
}

/* Base class related operations, such as eating, walking, saying and so on * *
void Animal_eat (animal_t *animal, char *food)
{
Animal->animal_ops->eat (food);
Return
}

void Animal_walk (animal_t *animal, int steps)
{
Animal->animal_ops->walk (steps);
Return
}

void Animal_talk (animal_t *animal, char *msg)
{
Animal->animal_ops->talk (msg);
Return
}

/* The destructor of the base class, need to display the call * *
void Animal_die (animal_t *animal)
{
ASSERT (animal!= NULL);

Free (animal);
Return
}
Implementation code for the doggy person dog class:


#include "animal-base.h"

typedef struct DOG_S_ dog_t;

struct Dog_s_ {
animal_t Base; /* Inherit from Animal base class * *

/* The following can also add dog-related properties and methods (function pointers), such as: * *
/* Char *owner; The owner of the dog * *
/* Void (*hunt) (const char *rabbit); Rabbit-Hunting Dog
};

extern dog_t * Dog_init ();
extern void Dog_die (dog_t * dog);

/*
* =============================================================================
*
* FILENAME:DOG.C
*
* Description:dog class derived from animal base class.
*
* created:12/31/2012 12:52:26 PM
*
* Author:fu haiping (forhappy), haipingf@gmail.com
* Company:ict (Institute of Computing Technology, CAS)
*
* =============================================================================
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "Dog.h"

static void Eat (char *food);

static void walk (int steps);

static void Talk (char *msg);

dog_t * Dog_init ()
{
dog_t *dog = (dog_t *) malloc (sizeof (dog_t));
animal_t *animal = (animal_t *) animal_init ("DOGGGGGGGGGGGGG");
memcpy (& (Dog->base), animal, sizeof (animal_t));

Dog->base.animal_ops->eat = eat;
Dog->base.animal_ops->walk = walk;
Dog->base.animal_ops->talk = talk;

Free (animal);
return dog;
}

void Dog_die (dog_t *dog)
{
/* Nothing todo here. */
}

static void Eat (char *food)
{
printf ("I ' m a dog, I eat%s\n", food);
}

static void walk (int steps)
{
printf ("I ' m a dog, I can jump%d steps one time\n", steps);
}

static void Talk (char *msg)
{
printf ("I ' m a dog, I talk my language%s\n", msg);
}
The implementation code for the Meow (CAT Class):


/*
* =============================================================================
*
* Filename:cat.h
*
* Description:cat class derived from animal base class.
*
* created:12/31/2012 12:44:05 PM
*
* Author:fu haiping (forhappy), haipingf@gmail.com
* Company:ict (Institute of Computing Technology, CAS)
*
* =============================================================================
*/
#include "animal-base.h"

typedef struct CAT_S_ cat_t;

struct Cat_s_ {
animal_t Base; /* Inherit from Animal base class * *

/* The following can also add cat-related properties and methods (function pointers), such as: * *
/* Char *owner; Cat's owner * *
/* Void (*hunt) (const char *rabbit); Rabbit-Hunting Dog
};

extern cat_t * Cat_init ();
extern void Cat_die (cat_t * cat);

/*
* =============================================================================
*
* FILENAME:CAT.C
*
* Description:cat class derived from animal base class.
*
* created:12/31/2012 12:52:26 PM
*
* Author:fu haiping (forhappy), haipingf@gmail.com
* Company:ict (Institute of Computing Technology, CAS)
*
* =============================================================================
*/
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include "Cat.h"

static void Eat (char *food);

static void walk (int steps);

static void Talk (char *msg);

cat_t * Cat_init ()
{
cat_t *cat = (cat_t *) malloc (sizeof (cat_t));
animal_t *animal = (animal_t *) animal_init ("Cat");
memcpy (& (Cat->base), animal, sizeof (animal_t));

Cat->base.animal_ops->eat = eat;
Cat->base.animal_ops->walk = walk;
Cat->base.animal_ops->talk = talk;

Free (animal);
return cat;
}

void Cat_die (cat_t *cat)
{
/* Nothing todo here. */
}

static void Eat (char *food)
{
printf ("I ' m a cat, I eat%s\n", food);
}

static void walk (int steps)
{
printf ("I ' m a cat, I can jump%d steps one time\n", steps);
}

static void Talk (char *msg)
{
printf ("I ' m a cat, I talk my language%s\n", msg);
}
Finally, the test code is as follows:


/*
* =============================================================================
*
* FILENAME:MAIN.C
*
* Description:main test.
*
* created:12/31/2012 01:00:43 PM
*
* Author:fu haiping (forhappy), haipingf@gmail.com
* Company:ict (Institute of Computing Technology, CAS)
*
* =============================================================================
*/
#include <stdio.h>

#include "animal-base.h"
#include "Dog.h"
#include "Cat.h"

int main (int argc, const char *argv[])
{
dog_t *dog = Dog_init ();
cat_t *cat = Cat_init ();

/* Dog class Test * *
Animal_eat (dog, "Bones");
Animal_walk (dog, 5);
Animal_talk (dog, "Wuang wuang Wuang ...");

/* Cat class Test * *
Animal_eat (cat, "fish");
Animal_walk (CAT, 3);
Animal_talk (Cat, "Miao Miao Miao ...");

}
And, of course, a little Makefile:


All:main

MAIN:MAIN.O DOG.O CAT.O ANIMAL-BASE.O
Gcc-o $@ $^

Main.o:main.c

Cat.o:cat.c

Dog.o:dog.c

Animal-base.o:animal-base.c

. Phony:clean

Clean
RM main MAIN.O DOG.O CAT.O ANIMAL-BASE.O
The results of the final implementation are:


I ' m a dog, I eat bones
I ' m a dog, I can jump 5 steps one time
I ' m a dog, I talk my language Wuang Wuang Wu Ang ...
I ' m a cat, I eat fish
I ' m a cat, I can jump 3 steps one time
I ' m a cat, I talk my language Miao Miao miao...< /p>

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.