The pure c language implements object oriented analysis and shares with examples

  • 2020-04-02 02:09:42
  • OfStack

Object model of C language
Object-oriented features mainly include:
Encapsulate and hide the internal implementation
Inherit and reuse existing code
. Polymorphic, overwrite object behavior
1.1   encapsulation
Encapsulation is an information hiding technique, which is embodied in the description of the class and is an important feature of the object. Encapsulates the data and the method of processing the data (function) encapsulated as a whole, in order to realize the independent modules, makes users can only see the external characteristic of the object (object can accept which messages, has the ability to process), and object features within (save the internal state of private data and realize the processing ability of the algorithm) is hidden to the user. The purpose of encapsulation is to separate the use of an object by its designer from that of its owner, so that the consumer does not have to know the details of the behavior implementation, but simply USES the message provided by the designer to access the object.
In C, most functions are named as verbs + nouns, such as semaphore
Take_semaphore, focusing on the take action. In object-oriented programming, the opposite is true: rt_sem_take, the noun + verb form, focuses on the noun and represents the method of an object. In addition, for some methods, they are limited to objects, and they use static rhetoric to limit the scope of a file. In this way, some information that the user does not want to know is shielded in the wrapper, so that the user only sees the outer interface, thus forming the most basic object wrapper implementation in object-oriented.

Generally, objects belonging to a certain class will have a unified creation and destruction process.
Object memory data block already exists, need to initialize it rt_sem_init; The object memory data block has not yet been allocated, and the rt_sem_create needs to be created and initialized. One way to think of it is that the creation of an object (create) is based on the initialization of the object (init), and the creation action is a memory allocation action in comparison.
The corresponding two types of destructions are as follows:
Rt_sem_detach, semaphore object initialized by rt_sem_init
.rt_sem_delete the semaphore object created by rt_sem_create.

1.2   inheritance
Inheritance is the mechanism by which subclasses automatically share data and methods between their parent classes. It is represented by the derived functionality of the class. A class directly inherits all the descriptions of other classes, and can be modified and extended. Inheritance is transitive. Inheritance is divided into single inheritance (a subclass has only one parent) and multiple inheritance (a class has multiple parents, which is not supported by the current rt-thread object system). The objects of the class are closed, and if there is no inheritance mechanism, there will be a lot of duplication of data and methods in the class object. Inheritance not only supports system reusability, but also promotes system extensibility.

Similar implementation code is as follows:



struct  parent_class
{
  int  a,  b;
  char  *str;
};

struct  child_class
{
  struct  parent class  p;
  int  a,  b;
};

void  func()
{
  struct  child_class  obj,  *obj_ptr;  
  struct  parent_class  *parent_ptr;  
  obj_ptr  =  &obj;
  
  parent_ptr  =  (struct  parent*)  &obj;
  
  parent ptr->a  =  1;
  parent ptr->b  =  5;
  
  obj ptr->a  =  10;
  obj ptr->b  =  100;
}

In the above code, notice that the first member p in the child_class structure is declared in such a way that the starting position in the data of type child_class contains a variable of type parent_class. In the function func, obj is a child_class object, and as the structure type indicates, its preceding data should contain data of type parent_class. Parent_ptr points to the first address of the obj variable, the p object in the obj variable, in the mandatory type assignment on line 21. Okay, so parent_ptr now points to
A true parent type structure, then you can access its members in a parent way, and of course you can use functions related to the parent structure to process the internal data, because a normal, correct code does not cross the line to access data outside the parent structure. Through this basic structure layer by layer, the simple persistence of the object is reflected: the parent object is placed at the front of the block, and the code can be cast to get a pointer to the parent object.

1.3   polymorphism
The object ACTS based on the message it receives. When the same message is received by different objects, completely different actions can occur, a phenomenon known as polymorphism. With polymorphism, a user can send a generic message, leaving all implementation details up to the object receiving the message, so that the same message can invoke different methods. For example, abstract devices have uniform read-write interfaces. Serial port is a kind of equipment, should also support the device read and write. However, the read and write operation of the serial port is unique to the serial port and should not be used with other devices
The operation is identical, for example, the operation of the serial port should not be applied to the SD card device. The implementation of polymorphism is supported by inheritance, which takes advantage of the hierarchical relationship of class inheritance to store general-purpose protocols as high up in the class hierarchy as possible, while placing the different methods of implementing this functionality at lower levels so that the objects generated at these lower levels can respond differently to the general-purpose messages.

Object model adopts the form of pointer in structural encapsulation to achieve the effect of polymorphism in object orientation, such as:



struct  parent_class
{
  int  a;
  
  void  (*vfunc)(int  a);
}

void  parent_class_vfunc(struct  parent_class  *self,  int  a)
{
  assert(self  !=  NULL);
  assert(slef->vfunc  !=  NULL);
  
  self->vfunc(a);
}

struct  child_class
{
  struct  parent_class  parent;
  int  b;
};

void  child_class_init(struct  child_class*  self)
{
  struct  parent_class*  parent;
  
  parent  =  (struct  base_class*)  self;
  assert(parent  !=  NULL);

  
  parent->vfunc  =  child_class_vfunc;
}

static  void   child class vfunc(struct  child class*self,  int  a)
{
  self->b  =  a  +  10;
}


#include <stdio.h>
#include <stdlib.h>
//interface
#ifndef Interface
#define Interface struct
#endif
//class
#ifndef Class
#define Class struct
#endif
// The abstract shape class
Class Shape;
typedef Class Shape shape;
// The abstract shape class Method declaration of 
shape* Shape(int edges);
int shape_getEdges(shape *);
int shape_getArea(void);
void _Shape(shape *);
// triangle class
Class Triangle;
typedef Class Triangle triangle;
// triangle class Method declaration of 
triangle * Triangle(int bottom, int height);
int triangle_getEdges(triangle *);
int triangle_getArea(triangle *);
void _Triangle(triangle *);
// rectangular class
Class Rectangle;
typedef Class Rectangle rectangle;
// rectangular class Method declaration of 
rectangle * Rectangle(int bottom, int height);
int rectangle_getEdges(rectangle *);
int rectangle_getArea(rectangle *);
void _Rectangle(rectangle *);
// The abstract shape class implementation 
Class Shape
{
    int edges;
    int (*getEdges)(shape*);
    int (*getArea)(void);
};
// The shape of class The constructor 
shape* Shape(int edges)
{
    shape * obj = (shape *) malloc(sizeof(shape));
    obj->edges = edges;
    obj->getEdges = shape_getEdges;
    obj->getArea = shape_getArea;
    return obj;
}
int shape_getEdges(shape* obj)
{
    return obj->edges;
}
int shape_getArea(void)
{
    return -1;
}
// The shape of class The destructor 
void _Shape(shape * obj)
{
    if(obj == NULL)
        return; 
    free(obj); 
}
// triangle class implementation 
Class Triangle
{
    shape * super;
    int bottom;
    int height;
    int (*getEdges)(triangle *);
    int (*getArea)(triangle *);
};
// triangle class The constructor 
triangle * Triangle(int bottom, int height)
{
    triangle* obj = (triangle*) malloc(sizeof(triangle));
    //Call the Shape constructor to implement inheritance
    obj->super = Shape(3);
    obj->bottom = bottom;
    obj->height = height;
    obj->getEdges = triangle_getEdges;
    obj->getArea = triangle_getArea;
    return obj;
}
int triangle_getEdges(triangle * obj)
{
    return obj->super->edges;
}
int triangle_getArea(triangle * obj)
{
    return (obj->bottom * obj->height) / 2;
}
// triangle class The destructor 
void _Triangle(triangle * triangle)
{
    _Shape(triangle->super); 
    if(triangle == NULL)
    {
        return; 
    }
    free(triangle); 
}
// rectangular class implementation 
Class Rectangle
{
    shape * super;
    int bottom;
    int height;
    int (*getEdges)(rectangle *);
    int (*getArea)(rectangle *);
};
// rectangular class The constructor 
rectangle * Rectangle(int bottom, int height)
{
    rectangle * obj = (rectangle *)malloc(sizeof(rectangle));
    //Call the Shape constructor to implement inheritance
    obj->super = Shape(4);
    obj->bottom = bottom;
    obj->height = height;
    obj->getEdges = rectangle_getEdges;
    obj->getArea = rectangle_getArea;
    return obj;
}
int rectangle_getEdges(rectangle * obj)
{
    return obj->super->edges;
}
int rectangle_getArea(rectangle * obj)
{
    return (obj->bottom * obj->height);
}
// rectangular class The destructor 
void _Rectangle(rectangle * obj)
{
    _Shape(obj->super);
    if(obj == NULL)
    {
        return;
    }
    free(obj);
}
//test
void main(){
    shape* shapeObj = Shape(0);
     printf("%dn", shapeObj->getEdges(shapeObj));
    printf("%dn", shapeObj->getArea());
    _Shape(shapeObj);
    triangle* triangleObj = Triangle(4, 5);
    printf("%dn", triangleObj->getEdges(triangleObj));
    printf("%dn", triangleObj->getArea(triangleObj));
    _Triangle(triangleObj);
    rectangle* rectangleObj = Rectangle(4, 5);
    printf("%dn", rectangleObj->getEdges(rectangleObj));
    printf("%dn", rectangleObj->getArea(rectangleObj));
    _Rectangle(rectangleObj);
}


Related articles: