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>