Think about the SWITC case and if else if ... when we encounter a multiple-statement branch.
These 2 ways are really simple in terms of coding, however, when the branch reaches a certain number, especially within the branch has nested large pieces of code or nested branches, the code will appear to be unusually bloated, very difficult to maintain, for if too many branches of if if statement too much judgment sentence, will affect efficiency.
3 Alternative methods are described:
1. Using map, you need to build trees and nodes, consume more memory than arrays, and query time complexity log (N), but it is easy to expand.
2. The use of arrays, query Direct index positioning, generally speaking we are a continuous initialization of the array, but also means that the index (TYPE_FUNC) to the function of the mapping to continuous,
So using an array index on the extension: for example, adding and deleting elements is a little bit of a hassle.
3. Use the attributes of C + +---Abstract inheritance to implement, this article only talk about the first 2 kinds of use, this method will be supplemented later.
Copy Code code as follows:
Animals will do some action
Enum Type_func
{
Type_begin =-1,
Type_eat,
Type_sleep,
Type_walk,
Type_run,
Type_smile,
Type_cry,
Type_jump,
Type_max_size,
};
Class Canimal
{
Public
typedef int (canimal::* ptr_func) (bool);
Protected
Static map<type_func,ptr_func> S_map;
Static Ptr_func s_array[type_max_size];
Public
Canimal ()
{
memset (s_array,0,sizeof (S_array));
Init ();
}
The return value and parameters of the mapping function need to be unified
int eat (bool= true) {return printf ("Eatn"), 1;}
int sleep (bool= true) {return printf ("SLEEPN"), 1;}
int Walk (bool= true) {return printf ("Walkn"), 1;}
int run (bool= true) {return printf ("Runn"), 1;}
int Smile (bool= true) {return printf ("Smilen"), 1;}
int Cry (bool= true) {return printf ("Cryn"), 1;}
int jump (bool= true) {return printf ("Jumpn"), 1;}
Class
void Init ()
{
S_map[type_eat] = &CAnimal::eat;
S_map[type_sleep] = &CAnimal::sleep;
S_map[type_walk] = &CAnimal::walk;
S_map[type_run] = &CAnimal::run;
S_map[type_smile] = &CAnimal::smile;
S_map[type_cry] = &CAnimal::cry;
S_map[type_jump] = &CAnimal::jump;
S_array[type_eat] = &CAnimal::eat;
S_array[type_sleep] = &CAnimal::sleep;
S_array[type_walk] = &CAnimal::walk;
S_array[type_run] = &CAnimal::run;
S_array[type_smile] = &CAnimal::smile;
S_array[type_cry] = &CAnimal::cry;
S_array[type_jump] = &CAnimal::jump;
}
The general practice is to SWITC case or if else ...
It's not so bad here, on the one hand, I encapsulate each module's content in the corresponding function.
The inside of the branch will look relatively concise, and the actual code may not be the way you see it.
void Process (Type_func type)
{
Switch (type)
{
Case Type_eat:eat (); Break
Case Type_sleep:sleep (); Break
Case Type_walk:walk (); Break
Case Type_run:run (); Break
Case Type_smile:smile (); Break
Case Type_cry:cry (); Break
Case Type_jump:jump (); Break
}
}
It's a familiar feeling! :)
void Process2 (Type_func type)
{
if (type_eat = = type)
{
Eat ();
}
else if (type_sleep = = type)
{
Sleep ();
}
else if (Type_walk = = type)
{
Walk ();
}
else if (Type_run = = type)
{
Run ();
}
else if (type_smile = = type)
{
Smile ();
}
else if (type_cry = = type)
{
Cry ();
}
else if (type_jump = = type)
{
Jump ();
}
}
Using map mappings
void Processbyusemap (int key, BOOL Val)
{
Map<type_func,ptr_func>::iterator it = S_map.find ((type_func) key);
if (it!= s_map.end ())
{
Ptr_func Pfun = it->second;
if (Pfun)
(This->*pfun) (Val);
}
}
Using array mappings
void Processbyusearray (int key, BOOL Val)
{
Array
if (Type_begin < key && type_max_size > key)
{
Ptr_func pfun = S_array[key];
if (Pfun)
(This->*pfun) (Val);
}
}
Using map mappings
int operator[] (int key)
{
Map<type_func,ptr_func>::iterator it = S_map.find ((type_func) key);
if (it!= s_map.end ())
{
Ptr_func Pfun = it->second;
if (Pfun) return (This->*pfun) (false);
}
return NULL;
}
Using array mappings
int operator () (int key,bool val)
{
if (Type_begin < key && type_max_size > key)
{
Ptr_func pfun = S_array[key];
if (Pfun) return (This->*pfun) (Val);
}
return NULL;
}
};
Map<type_func, Canimal::p tr_func> canimal::s_map;
Canimal::p tr_func canimal::s_array[type_max_size];
//////////////////////////////////////////////////////////////////////////
Non-member function
void func_eat (int = 0) {}
void Func_run (int = 0) {}
void Func_walk (int =0) {}
void func_cry (int = 0) {}
typedef void (*PTRFUN) (int);
Map<type_func,ptrfun> G_map;
Ptrfun G_array[type_max_size];
int _tmain (int argc, _tchar* argv[])
{
//////////////////////////////////////////////////////////////////////////
For illustration purposes, the following code does not perform security checks
2 usages of non-member function mapping
Init
G_map[type_eat] = func_eat;
G_map[type_run] = Func_run;
G_map[type_walk] = Func_walk;
G_map[type_cry] = func_cry;
G_array[type_eat] = func_eat;
G_array[type_run] = Func_run;
G_array[type_walk] = Func_walk;
G_array[type_cry] = func_cry;
Using
G_map[type_eat] (1);
G_map[type_run] (2);
G_map[type_walk] (3);
G_map[type_cry] (4);
G_array[type_eat] (1);
G_array[type_run] (2);
G_array[type_walk] (3);
G_array[type_cry] (4);
//////////////////////////////////////////////////////////////////////////
member function Mappings use
Canimal Dog;
Dog.process (type_eat);
Dog.processbyusemap (type_run,true);
Dog.processbyusearray (Type_cry,false);
Dog[type_walk];
Dog (type_sleep,true);
Dog (Type_run,false);
return 1;
}