Pure C language realizes simple encapsulation inheritance mechanism

Source: Internet
Author: User

0 Inheritance is the foundation of OO Design

Inheritance is the basic part of OO design, it is also the basis of realizing polymorphism, c++,c#,objective-c. Java. Php. JavaScript and other languages designed for OO, the language itself provides direct support for implementing inheritance. But the language that follows C/unix design philosophy, never limits the programming style. It also provides basic support for implementing OO. Let's take a look at how to implement inheritance in the C language.

1 The meaning of inheritance on the memory layout level

Almost all of the program apes now know the abstract meaning of inheritance and are familiar with examples of animals that have been used to the dogs. Here, we put aside the abstract world and go deep into the detailed implementation of inheritance. Of course, different languages do not have the same implementation mechanism for inheritance, but it is good to understand that one of the typical implementation details is an understanding of inheritance. Here we illustrate with C + + as an example.

class B{    int x;    int y;    int z;};class C : B{    float f;    char s[10];};

The code above indicates that subclass C inherits the parent Class B. The following is a memory layout for an instance (object) of Class C.


The C object consists of two parts, and the red area is the part that inherits from B, and the blue area is unique to itself. In this way, the red part can be considered as a class B object entirely.

2 two ways to implement inheritance using structs 2.1 Parent class object as a member of a subclass

After understanding the principle of inherited memory layout, it is easy to implement inheritance with C. The easiest way to think about it is as follows:

struct B{    int x;    int y;    int z;};struct C{    struct B objB;    float f;    char s[10];};

The preceding code implements inheritance by including a member of type B in C, which is straightforward. But some of them are not very convenient to use.

    struct C objC;    10;    ((struct10;

There are two ways to access member X of the parent class. One is objc.objb.x, and the other is (struct b*) &objc)->x = 10.

Neither of these approaches seems straightforward enough. It is very frequent to access the parent class members in the subclass method.

void c_member_method(struct C* pObjC){    20/* 訪问父类成员 */    0.23f/* 訪问自身成员 */}

The first way, it feels more like OB style. Rather than OO.


Another method, which must be forced type conversion, feels that the syntax is not aesthetically pleasing.

2.2 Subclasses include all parent class members
struct C{    int x;    int y;    int z;    float f;    char s[10];};

The entire parent class member is as a member of the subclass. This way the class object visits the inherited members very directly.

void c_member_method(struct C* pObjC){    20/* 訪问父类成员 */    0.23f/* 訪问自身成员 */}void main(){    struct C objC;    10;}

Looks good, and there's actually a big problem with project: It's hard to maintain. For example, whenever a subclass is created. All parent members must be written as-is, and the subclass needs to make the same changes when the parent class defines the changes. Once the parent class is small, maintaining such an inheritance relationship will be a nightmare.

So how to solve it?
The method is out of the box, that is, the C-language preprocessing macro defines the # define. For example, see the following:

#define B_STRUCT \    int x;     int y;     int zstruct B{    B_STRUCT;};struct C{    B_STRUCT;    float f;    char s[10];};

When the inheritance hierarchy is deeper. For example C inherits B,d C, can copy this method.

#define B_STRUCT \    int x;     int y;     int zstruct B{    B_STRUCT;};#define C_STRUCT \    B_STRUCT;     float f;     char s[10]struct C{    C_STRUCT;};#define D_STRUCT \    C_STRUCT;     double dstruct D{    D_STRUCT;};

Defined by a macro. It is easy to implement and maintain such an inheritance relationship.

3 encapsulation and inheritance of methods (member functions)

There is no concept of member functions in C, and the language itself is not supported.

It is almost impossible to implement a real member function in C unless it is embedded in assembly language. Instead of using assembly language, it's better to use C + + directly.

Therefore, we do not pursue formal member functions, just implement the meaning of the member functions-(operations on a given type of object) function, and use the name of the function with the name prefix of the structure named.

We'll still use the example above to illustrate this.

typedefstruct B B;staticvoid/* 类B的成员函数 */{}typedefstruct C C;staticvoid/* 类C的成员函数 */{}

There are two scenarios for the invocation of a member function: (1) The external code calls the member function, and (2) the member function of the parent class is called in the Child class member function;

staticvoid c_member_function(C* pobjC){    /* 子类成员函数内部调用父类成员函数 */}void main(){    malloc(sizeof(C));    b_member_function((B*)pObjC);  /* 外部代码调用成员函数 */    free(pObjC);}

In both cases, you need to cast the arguments to the parent type. The C compiler has no knowledge of the type inheritance relationships and cannot be syntactically self-supporting inheritance, so it is only possible to manually force type conversions.

Some people like to further simulate member functions. Stores the address of the full member function as a member variable of the pointer type inside the struct body.

For example, the following:

#define B_STRUCT \    int x;     int y;     int z;     void (*pb_member_function1)(B*);     voidint arg)struct B{    B_STRUCT;   };/* 初始化B对象的同一时候初始化 */malloc(sizeof(B));b->pb_member_function1 = b_member_function1;b->pb_member_function2 = b_member_function2;/* 调用 */b->b_member_function1(b);

This form is closer to the "member function". But at the same time, it also brings additional memory overhead and code volume.

To reduce memory consumption, it was suggested that all member function pointers would not be stored in the object at all, but rather simply a pointer to the address list of the member function. After all, all instances (objects) of the same type share the same set of member functions.

/ * Member Method table for Type B * /Const structb_methodtable{void(*pb_member_function1) (b*);void(*pb_member_function2) (B*,intARG);} b_method_table{B_member_function1, B_member_function2,};#define B_STRUCT \    intXintYintZstructB_methodtable * pmethodtable;structb{b_struct; };/ * Initialize the B object at the same time to initialize * /b* B =malloc(sizeof(B)); B->pmethodtable = &b_method_table;/ * call * /B->pmethodtable->pb_member_function1 (b);

This reduces the memory footprint and the amount of code to some extent, but the call notation of the team member function becomes cumbersome and unnatural.

4 to what extent?

Use C language to do OO development, to master the good one degree. Do not over-pursue the OO language C + + simulation, completely analog C + +, rather than simply use C + + directly.

    • Some language features cannot be emulated, such as access qualifiers such as private,protected in C + +. The this pointer of the member function. More attention should be paid to the simulation of meaning. OO is achieved through some naming rules and conventions.

    • Never violate the design philosophy of C: The program Ape controls everything, directly and concisely.

This degree of certainty needs to be based on detailed project size and requirements. Is the practice of groping out. The theoretical optimal value cannot be given.

Pure C language realizes simple encapsulation inheritance mechanism

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.