程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> 關於C++ >> C語言利用 void 類型指針實現面向對象類概念與抽象。

C語言利用 void 類型指針實現面向對象類概念與抽象。

編輯:關於C++

C語言利用 void 類型指針實現面向對象類概念與抽象。。本站提示廣大學習愛好者:(C語言利用 void 類型指針實現面向對象類概念與抽象。)文章只能為提供參考,不一定能成為您想要的結果。以下是C語言利用 void 類型指針實現面向對象類概念與抽象。正文


不使用C++時,很多C語言新手可能認為C語言缺乏了面向對象和抽象性,事實上,C語言通過某種組合方式,可以間接性的實現面對對象和抽象。

不過多態和繼承這種實現,就有點小麻煩,但是依然可以實現。

核心:

利用 void 類型指針,可以指向任意類型指針。

1 //基本代碼
2 void* p;
3 p = (void*) "HelloWorld";
4 
5 char* str;
6 str = (char*) p;
7 
8 printf("%s",str);//輸出 HellWord

 

通過這個我們就可以實現抽象性,讓數據結構或函數不再與特定的類型高耦合。

從而像C++模板一樣,處理任何類型元素。

 

面向對象的類概念:

類自身會有一組屬性和一組公開或私有的方法函數,外界可以實例化一個,從而創建一個類的對象。

這在C語言裡面,可以通過 struct 關鍵字來定義類似於類的概念結構。

 

我們現在來實現一組抽象的面向對象類的列表容器(List),可以裝載任意對象指針:
#include <stdio.h>
#include <stdlib.h>


#define SIEZ_NAME 200
#define Class struct 

//雙向鏈表
typedef Class Struct_List_Node{
    void * item;
    struct Struct_List_Node * next;
    struct Struct_List_Node * previous;
}WList_Node;

typedef Class Struct_WList{
    //類的屬性
    WList_Node* head;
    WList_Node* end;
    int length; 

    //公開方法函數
    void (*push)(Class Struct_WList*,void*);
    void (*destroy)(Class Struct_WList* );
    void* (*pop)(Class Struct_WList* );
    void* (*shift)(Class Struct_WList* );

}WList;


void WList_push(WList* self,void* item){
    WList_Node* new_node = (WList_Node* )malloc(sizeof(WList_Node));
    new_node->item = item;
    new_node->next = NULL;
    new_node->previous = NULL;
    printf("Push %p\n", new_node);
    self->length++;
    if(self->head == NULL){
        self->head = self->end = new_node;
    }else{
        new_node->previous = self->end;
        self->end = self->end->next = new_node;
    }
    
}

void* WList_pop(WList* self){
    if(self->length <= 0 )return NULL;
    WList_Node* pop_node;
    self->length--;
    pop_node = self->end;
    pop_node->previous->next = NULL;
    void* return_p = pop_node->item;
    free(pop_node);
    return return_p;

}

void* WList_shift(WList* self){
    if(self->length <= 0 )return NULL;
    WList_Node* pop_node;
    self->length--;
    pop_node = self->head;
    self->head = self->head->next;
    self->head->previous = NULL;
    void* return_p = pop_node->item;
    free(pop_node);
    return return_p;
}

void WList_destroy(WList* self){
    WList_Node* destroy_node;
    while(self->head){
        destroy_node = self->head;
        self->head = self->head->next;
        printf("WList_destroy: %p\n",destroy_node);
        free(destroy_node);
    }   
}

void WList_init(WList* self){
    self->length = 0;
    self->head = self->end = NULL;
    self->push = WList_push;
    self->pop = WList_pop;
    self->shift = WList_shift;    
    self->destroy = WList_destroy;
}


//測試類型
typedef Class struct_book{
    char name[SIEZ_NAME];
    int price;
}Book;

int main(){
    //測試
    WList* list = (WList*) malloc(sizeof(WList));

    WList_init(list);

    list->push(list,"Head !");//C可以省略強制轉換,但不建議
    list->push(list,(void *)'S');
    list->push(list,(void *)66666);
    list->push(list,(void *)2);
    list->push(list,(void *)(char *) malloc(sizeof(char)*10));
    list->push(list,(void *)"wc");
    list->push(list,(void *)(char *) malloc(sizeof(char)*10));
    list->push(list,(void *)(char *) malloc(sizeof(char)*52));
    list->push(list,(void *)(char *) malloc(sizeof(char)*100));
    list->push(list,(void *)(Book *) malloc(sizeof(Book)*10));
    list->push(list,(void *)"HelloWorld!!!!");

    printf("\nFrist List length:%d\n\n", list->length);
    printf("Head String: %s \n\n",(char *) list->shift(list));
    printf("End String: %s \n\n", list->pop(list));
    printf("List length:%d\n", list->length);

    list->destroy(list);

    getchar();
    return 0;
}

 

這樣我們就創建了解耦的通用列表容器。init相當於構造函數,destroy相當於析構函數。

 

仔細觀察代碼,編程list->xxx 即可以使用所有本身的公開函數,只是初始化的時候需要使用一下init函數。

然後我們每次將第一個參數作為自身傳遞,即可以像Python面向對象一樣(雖然它自動傳遞),實現面向對象的類。

當然了,面向對象不止包括類,還有多態,抽象,接口,繼承等等一系列行為,這些在C語言實現略為麻煩。

 

感謝耐心閱讀。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved