Implementation of C language relay and Polymorphism

Source: Internet
Author: User
Tags switch case

The following content is a combination of multiple articles and a bit of your own understanding. The purpose is to give yourself a note after reading their article. The addresses of these articles are provided at the end.

Polymorphism can be implemented in the following ways:
(1) Use VOD * (Universal pointer) to implement "polymorphism during compilation ".
(2) Use function pointers to achieve "Runtime polymorphism ".
(3) Use type such as struct struct_name {

...............................
Char temp [0]; // or char * temp;
};
This form.

For example (1:

Void handlemsg (unsinged int ID, void * P)
{
Msg1 * P1;
Msg2 * P2;

Switch (ID)
{
Case key1:
P1 = (msg1 *) P;
// Do something
Break;
Case key2:
P2 = (msg2 *) P;
// Do something
Break;
Default:
Break;
}
}

This example may not indicate the polymorphism of the function during compilation, because the conversion between the function pointer and VOD * is not used. I didn't give such examples because I wanted to avoid this kind of usage.
For example (2:
# Ifndef c_class
# Define c_class struct
# Endif

C_class {

C_class A * a_this;
Void (* Foo) (c_class A * a_this );
Int;

Int B;

};

C_class B {// B inherits

C_class B * B _this; // order is important
Void (* Foo) (c_class B * BThis); // virtual function
Int;
Int B;
Int C;
};

Void B _f2 (c_class B * BThis)
{
Printf ("It is B _fun/N ");
}

Void a_foo (c_class A * athis)
{

Printf ("it is A. A = % d/N", Athis-> A); // or here
}

Void B _foo (c_class B * BThis)
{
Printf ("It is B. C = % d/N", BThis-> C );
}

Void a_creat (struct a * P)
{
P-> Foo = a_foo;
P-> A = 1;
P-> B = 2;
P-> a_this = P;
}

Void B _creat (struct B * P)
{
P-> Foo = B _foo;
P-> A = 11;
P-> B = 12;
P-> C = 13;
P-> B _this = P;

}

Int main (INT argc, char * argv [])
{

C_class A * ma,;
C_class B * MB, B;

A_creat (& A); // instantiate
B _creat (& B );

MB = & B;
MA = &;

MA = (c_class A *) MB; // introduce the polymorphism pointer

Printf ("% d/N", ma-> A); // unfortunately, the function variable does not have private

Ma-> Foo (MA); // Polymorphism
A. Foo (& A); // It Is Not A polymorphism
B _f2 (& B); // member functions. function pointers are not used because of efficiency issues.
Return 0;
}

Implement inheritance in C.
For example (1), there is a major drawback, that is, the lack of type security. In this case, inheritance can be used to ensure type security.

Typedef struct tagt_msgheader {
Int ID;
//...
} Msgheader;

Typedef struct tagt_msg1 {
Msgheader h;
Int;
Int B;
} Msg1;

Typedef struct tagt_msg2 {
Msgheader h;
Int C;
Int D;
} Msg2;

Then re-define the message processing function:

Void handlemsg (msgheader * pH)
{
Msg1 * P1;
Msg2 * P2;

Switch (pH-> ID)
{
Case key1:
P1 = (msg1 *) (ph );
// Do something
Break;
Case key2:
P2 = (msg2 *) pH;
// Do something
Break;
Default:
Break;
}
}

Inheritance ensures type security, but to ensure the flexibility of the inherited struct, the inherited variable msgheader H cannot be the first member variable, so p1 =

(Msg1 *) (ph) This forced conversion won't be able to get the correct P1 address, but by defining a macro to achieve this:

# Define containing_record (address, type, field) (type *)(/
(Pchar) (Address )-/
(Uint_ptr) (& (type *) 0)-> Field )))
This macro definition is the most common in Linux. In this way, the input msgheader pointer is macro-processed. No matter the position of msgheader H in the struct, the first address of the inherited struct can be obtained. In this way, the forced conversion is no problem.

By the way, explain this macro:
# Define containing_record (address, type, field) (type *) (char *) (PTR)-(unsigned long) (& (type *) 0) -> member )))

First look at & (type *) 0)-> field, which forcibly converts "0" to the pointer type, then the Pointer Points to "0" (Data Segment Base Address ). Because the pointer is of the "type *" type, you can obtain the address of a field variable with the "0" base address, this address is equal to the number of bytes from the field to the base address of the struct. The current address minus the offset address to get the address of the struct. Converts a pointer to the (type *) type.

To implement pure virtual classes in C, you can use function pointer members in the struct.

// ------------------ The function pointer in the struct is similar to the virtual function that must be implemented in the declared subclass -------------
Typedef struct
{
Void (* foo1 )();
Char (* foo2 )();
Char * (* foo3) (char * st );
} Myvirtualinterface;
//---------------------------------------------------------------------------------

// ------------------ Similar to the definition of pure virtual classes ---------------------------------------------
Myvirtualinterface * m_pinterface;
 
Domyact_setinterface (myvirtualinterface * pinterface)
{
M_pinterface = pinterface;
}

Void omyact_do ()
{
If (m_pinterface = NULL) return;
M_pinterface-> foo1 ();
C = m_pinterface-> foo2 ();
}
//---------------------------------------------------------------------------------

// -------------------------- Subclass 1 -------------------------------------------------
Myvirtualinterface st [Max];

// Define some functions to be implemented: act1_foo1, act1_foo2, act1_foo3

Myvirtualinterface * act1_creatinterface ()
{
Index = findvalid () // Object pool or use malloc! Should be applied outside and instantiated
If (Index =-1) return NULL;
St [Index]. foo1 = act1_foo1; // act1_foo1 must be implemented in the following
St [Index]. foo2 = act1_foo2;
St [Index]. foo3 = act1_foo3;
Return & St [Index];
}
// Configure //-----------------------------------------------------------------------------------

// -------------------------- Main function ---------------------------------------------------
If (P = act1_creatinterface ())! = NULL)
{
List_addobject (& list, P); // Add all
While (P = list_getobject ())
{
Domyact_setinterface (p); // use the interface to replace the switch case of the original large space
Domyact_do (); // ignore the specific action, just do it
}
}
// Configure //-----------------------------------------------------------------------------------

If the parent class is not a pure virtual class, use a macro In the subclass to implement the virtual function.

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
St [Index]. foo2 = actbyother1_foo2; //
St [Index]. foo3 = actbyother1_foo3; //
Return & St [Index];
}

# Define actbyother1_foo1 act1_foo1 // This is the inheritance
Actbyother1_dobyother () {}// Of course, you can add a new implementation.

Reference:

[1] http://blog.csdn.net/baoxingbo/articles/56406.aspx

[2] http://hi.baidu.com/blue_never_died/blog/item/b05f242d389bb734349bf7dd.html

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.