I believe many people have read the design pattern book for the implementation of the C language polymorphism. What do you know? Bridge, proxy, and factory are all based on abstract classes. Abstract objects are the core of this process. In fact, I think the core issue of framework-based programming is abstraction. using abstract objects to build the main framework of a program is a common idea of object-oriented programming. Building a skeleton with abstraction, coupled with polymorphism, forms a complete program. Because the C ++ language implements inheritance and polymorphism, this programming concept is used? It is quite common in C ++. It can be said that virtual (polymorphism) is the soul of VC. However, we almost forget this polymorphism when using the C language. I often hear the predecessors say, class? Polymorphism? We use C. Forget this. Unfortunately, I am a stubborn person. Why not use such a good thing. I'm glad to see the polymorphism in C in some recent pure C code! Next, let me hear about it. 1. What is the interface in VC? The Chinese explanation is the interface. In fact, it represents a pure virtual class. However, what I want to say is that the interface in VC is actually struct. Looking for the interface definition, you can find the macro definition: # ifndef interface # define interface struct # endif and, in VC, if a class has a virtual function, there will be a vtable in the class, which is actually a list of virtual functions. In fact, C ++ is developed from C, but it supports many new features at the language level. In C, we can also use such features, the premise is that we have to implement it on our own. 2. How to implement a pure virtual class in C (I call it a pure virtual structure) is more advanced than above. I believe everyone has suddenly become enlightened. You can use the struct combination function pointer to implement pure virtual classes. Example: typedef struct {void (* foo1) (); char (* foo2) (); char * (* foo3) (char * st);} myvirtualinterface; in this case, we should use the bridge mode in the main framework. (Our main class is domyact, and the specific implementation class of the interface is act1 and Act2.) I will introduce these "classes" in sequence ". (In c, the "class" is described earlier. Here we use an earlier array method.) Main class domyact: The main class contains myvirtualinterface * m_pinterface; the main class has the following functions: domyact_setinterface (myvirtualinterface * pinterface) {m_pinterface = pinterface;} domyact_do () {If (m_pinterface = NULL) return; m_pinterface-> foo1 (); C = m_pinterface-> foo2 ();} sub-class act1: implements the virtual structure, including myvirtualinterface st [Max]; has the following functions: myvirtualinterface * act1_creatinterface () {Index = findvalid () // Object pool or use malloc! The request should be left outside, and if (Index =-1) return NULL; ST [Index] should be instantiated. foo1 = act1_foo1; // act1_foo1 must be implemented in the following steps. foo2 = act1_foo2; ST [Index]. foo3 = act1_foo3; Return & St [Index];} The subclass Act2 is the same as above. In Main, assume there is an object list. If (P = act1_creatinterface () is the myvirtualinterface pointer stored in the list ())! = NULL) list_addobject (& list, P); // Add all while (P = list_getobject () {domyact_setinterface (P ); // use the interface instead of the switch case domyact_do (); // ignore the specific action, just do it} free all. In Microsystems, such as embedded systems, the object pool technology is usually used. In this case, you do not need to consider the release issue (the object pool has no space in advance, and attach is used, apply for an array in a function and temporarily allocate space to the object pool. The function ends and the Object pool is released.) However, in the PC environment, the program size is large, more importantly, some special requirements make it necessary to use malloc to extend the object lifecycle beyond the applied function body. In fact, even in C ++, the automatic release of new objects is always a headache. The new standard introduces smart pointers. However, for me personally, I think it is untrustworthy to give the whole problem of memory release to the machine, and it can only achieve the optimal performance. Do you know how difficult it is to design the Java garbage collection algorithm? The real world is complex. without a prior condition, it is necessary to obtain accurate results and their difficulties. So I said that programmers should keep free at all times. The robustness and self-defense of the program will be described in another article. 3. Let's look at the degradation of the pure virtual structure. If there is only one function in struct, what is it? At this time, if we do not use struct, what is the use of function pointers? We found that this degrades to the use of common function pointers. So sometimes I think object-oriented is just a form, not a technology. It is a viewpoint, not an algorithm. However, just like the relationship between carbon, graphite and diamond, although the molecular formula is C, the composition method is different and the performance is completely different! Sometimes, we are often troubled by trivial things in programming, and thus shift away from the center of gravity. In fact, the evolutionary features of programs are very important. It is possible that, for the first time, it was unsuccessful, but as long as it could evolve, it could develop. 4. advanced-class structure tree, the parent class is not a pure virtual class. In the previous section, we only talked about the situation that the parent class is a pure virtual structure. (We recommend that the base classes of all classes start with pure virtual classes), so what if the parent class is not a pure virtual structure when there are many classes. Hey, in fact, the implementation in C is much simpler than that in C ++. Because the functions in C are scattered. Macro definition is a good method here: for example, two classes of act1, actbyother1 "inherit" act1: myvirtualinterface * actbyother1_creatinterface () {Index = findvalid () // Object pool or use malloc if (Index =-1) return NULL; ST [Index]. foo1 = actbyother1_foo1; // act1_foo1 must be implemented in the following way in the St [Index]. foo2 = actbyother1_foo2; ST [Index]. foo3 = actbyother?foo3; Return & St [Index] ;}# define actbyother?foo1 act1_foo1 // This is inherited by actbyother?foo2 () {}// you can modify its implementation of actbyother?dobyother () {} // Of course, you can add a new implementation.
5. instance-see the source code of h264, where naltool is such a pure virtual structure.