純c說話完成面向對象剖析與示例分享。本站提示廣大學習愛好者:(純c說話完成面向對象剖析與示例分享)文章只能為提供參考,不一定能成為您想要的結果。以下是純c說話完成面向對象剖析與示例分享正文
C說話的對象化模子
面向對象的特點重要包含:
.封裝,隱蔽外部完成
.繼續,復用現有代碼
.多態,改寫對象行動
1.1 封裝
封裝是一種信息隱藏技巧,它表現於類的解釋,是對象的主要特征。封裝使數據和加工該數據的辦法(函數)封裝為一個全體,以完成自力性很強的模塊,使得用戶只能見到對象的外特征(對象能接收哪些新聞,具有那些處置才能),而對象的內特征(保留外部狀況的公有數據和完成加工才能的算法)對用戶是隱藏的。封裝的目標在於把對象的設計者和對象者的應用離開,應用者不用知曉行動完成的細節,只須用設計者供給的新聞來拜訪該對象。
在C說話中,年夜多半函數的定名方法是動詞+名詞的情勢,例如要獲得一個semaphore,會定名
成take_semaphore,重點在take這個舉措上。面向對象編程中恰好相反,定名為rt_sem_take,即名詞+動詞的情勢,重點在名詞上,表現了一個對象的辦法。別的關於某些辦法,僅局限在對象外部應用,它們將采取static修辭把感化規模局限在一個文件的外部。經由過程如許的方法,把一些不想讓用戶曉得的信息屏障在封裝裡,用戶只看到了外層的接口,從而構成了面向對象中的最根本的對象封裝完成。
普通屬於某個類的對象會有一個同一的創立,析構進程。
對象內存數據塊曾經存在,須要對它停止初始化 – rt_sem_init;對象內存數據塊還未分派,須要創立並初始化 – rt_sem_create。可以這麼以為,對象的創立(create)是以對象的初始化(init)為基本的,創立舉措比擬較而言多了個內存分派的舉措。
絕對應的兩類析構方法:
.由rt_sem_init初始化的semaphore對象 – rt_sem_detach;
.由rt_sem_create創立的semaphore對象 – rt_sem_delete.
1.2 繼續
繼續性是子類主動同享父類之間數據和辦法的機制。它由類的派生功效表現。一個類直接繼續其它類的全體描寫,同時可修正和擴大。繼續具有傳遞性。繼續分為單繼續(一個子類只要一父類)和多重繼續(一個類有多個父類,以後RT-Thread的對象體系不克不及支撐)。類的對象是各自關閉的,假如沒繼續性機制,則類對象中數據、辦法就會湧現年夜量反復。繼續不只支撐體系的可重用性,並且還增進體系的可擴大性。
相似的完成代碼以下法式清單:
/* 父類 */
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;
}
在下面代碼中,留意child_class構造中第一個成員p,這類聲明方法代表child_class類型的數據中開端的地位包括一個parent_class類型的變量。在函數func中obj是一個child_class對象,正像這個構造類型指導的,它後面的數據應當包括一個parent_class類型的數據。在第21行的強迫類型賦值中parent_ptr指向了obj變量的首地址,也就是obj變量中的p對象。好了,如今parent_ptr指向的是
一個真真實實的parent類型的構造,那末可以依照parent的方法拜訪個中的成員,固然也包含可使用和parent構造相干的函數來處置外部數據,由於一個正常的,准確的代碼,它是不會越界拜訪parent構造體之外的數據。經由這根本的構造體層層相套包括,對象簡略的繼存關系就表現出來了:父對象放於數據塊的最後方,代碼中可以經由過程強迫類型轉換取得父對象指針。
1.3 多態
對象依據所吸收的新聞而做出舉措。統一新聞為分歧的對象接收時可發生完整分歧的行為,這類景象稱為多態性。應用多態性用戶可發送一個通用的信息,而將一切的完成細節都留給接收新聞的對象自行決議,如是,統一新聞便可挪用分歧的辦法。例如:籠統裝備具有接口同一的讀寫接口。串口是裝備的一種,也應支撐裝備的讀寫。但串口的讀寫操作是串口所獨有的,不該和其他裝備
操作完整雷同,例如操作串口的操作不該運用於SD卡裝備中。多態性的完成遭到繼續性的支撐,應用類繼續的條理關系,把具有通用功效的協定寄存在類條理中盡量高的處所,而將完成這一功效的分歧辦法置於較低條理,如許,在這些低條理上生成的對象就可以給通用新聞以分歧的呼應。
對象模子采取構造封裝中應用指針的情勢到達面向對象中多態的後果,例如:
/* 籠統父類 */
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);
}
/* 繼續自parent class的子類 */
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>
//接口
#ifndef Interface
#define Interface struct
#endif
//類
#ifndef Class
#define Class struct
#endif
//籠統外形類
Class Shape;
typedef Class Shape shape;
//籠統外形類的辦法聲明
shape* Shape(int edges);
int shape_getEdges(shape *);
int shape_getArea(void);
void _Shape(shape *);
//三角形類
Class Triangle;
typedef Class Triangle triangle;
//三角形類的辦法聲明
triangle * Triangle(int bottom, int height);
int triangle_getEdges(triangle *);
int triangle_getArea(triangle *);
void _Triangle(triangle *);
//矩形類
Class Rectangle;
typedef Class Rectangle rectangle;
//矩形類的辦法聲明
rectangle * Rectangle(int bottom, int height);
int rectangle_getEdges(rectangle *);
int rectangle_getArea(rectangle *);
void _Rectangle(rectangle *);
//籠統外形類完成
Class Shape
{
int edges;
int (*getEdges)(shape*);
int (*getArea)(void);
};
//外形類結構函數
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;
}
//外形類析構函數
void _Shape(shape * obj)
{
if(obj == NULL)
return;
free(obj);
}
//三角形類完成
Class Triangle
{
shape * super;
int bottom;
int height;
int (*getEdges)(triangle *);
int (*getArea)(triangle *);
};
//三角形類結構函數
triangle * Triangle(int bottom, int height)
{
triangle* obj = (triangle*) malloc(sizeof(triangle));
//挪用Shape結構函數用於完成繼續
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;
}
//三角形類析構函數
void _Triangle(triangle * triangle)
{
_Shape(triangle->super);
if(triangle == NULL)
{
return;
}
free(triangle);
}
//矩形類完成
Class Rectangle
{
shape * super;
int bottom;
int height;
int (*getEdges)(rectangle *);
int (*getArea)(rectangle *);
};
//矩形類結構函數
rectangle * Rectangle(int bottom, int height)
{
rectangle * obj = (rectangle *)malloc(sizeof(rectangle));
//挪用Shape結構函數用於完成繼續
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);
}
//矩形類析構函數
void _Rectangle(rectangle * obj)
{
_Shape(obj->super);
if(obj == NULL)
{
return;
}
free(obj);
}
//測試
void main(){
shape* shapeObj = Shape(0);
printf("%d\n", shapeObj->getEdges(shapeObj));
printf("%d\n", shapeObj->getArea());
_Shape(shapeObj);
triangle* triangleObj = Triangle(4, 5);
printf("%d\n", triangleObj->getEdges(triangleObj));
printf("%d\n", triangleObj->getArea(triangleObj));
_Triangle(triangleObj);
rectangle* rectangleObj = Rectangle(4, 5);
printf("%d\n", rectangleObj->getEdges(rectangleObj));
printf("%d\n", rectangleObj->getArea(rectangleObj));
_Rectangle(rectangleObj);
}