C語言實現(xiàn)面向?qū)ο蠛头庋b

前言

今天的Windows應(yīng)用開發(fā)課上缭裆,教授讓我們用純C語言實現(xiàn)面向?qū)ο蟮拈_發(fā)和封裝键闺。如果用C++那實現(xiàn)面向?qū)ο笫禽p而易舉,但是用純C的話澈驼,emmm想想就頭大辛燥,光一個字符串的操作就搞了半天,和C++比起來缝其,C語言真的太“基礎(chǔ)”了挎塌,幾乎所有的方法都要自己寫。
這個代碼我硬鋼了兩天内边,一共寫了500行左右榴都,收獲還是蠻大的,算是比較完善的將方法封裝了起來漠其。

代碼要求

  • 用純C實現(xiàn)面向?qū)ο缶幊?/li>
  • 包含基類和一層子類嘴高,子類及其繼承的方法由用戶自己設(shè)定,但要有接口
  • 所有的方法都要進行封裝和屎,不能顯示出來參數(shù)類型

代碼實現(xiàn)結(jié)構(gòu)

首先拴驮,為了實現(xiàn)封裝而且不顯示參數(shù)類型,將所有的參數(shù)都設(shè)置為int類型(包括結(jié)構(gòu)體)柴信,通過int轉(zhuǎn)換為各種指針類型套啤,再由指針析取為實際類型進行參數(shù)的操作

所有的方法封裝到WinProc接口中颠印,通過其中的msg參數(shù)辨別進行哪一個方法的調(diào)用纲岭。另外,為了實現(xiàn)基類和子類接口的統(tǒng)一线罕,另外加了一個CallProc接口止潮,實現(xiàn)分配基類和子類的操作函數(shù)。

//封裝的窗口操作函數(shù)
int WinProc(int win, int msg, int param1, int param2) {
    switch (msg){
    case MOVE: move(win, param1, param2); break;
    case SET_POSITION:  SetPosition(win, param1, param2); break;
    case GET_POSITION: {Pos p = GetPosition(win);   return (int)&p; }break;
    
    case SET_SIZE: SetSize(win, param1, param2); break;
    case GET_SIZE: {WinSize p = GetSize(win);   return (int)&p; }break;
    
    case SET_TITLE: SetTitle(win, (char*)param1); break;
    case GET_TITLE: return (int)GetTitle(win); break;
    
    case PRINTWINDOW: PrintWindow(win); break;
    
    case CONSTRUCT: return ConstructBase(win); break;
    case DESTRACT: DestroyWindow(win); break;
    
    case MEM_GET: return getMem(win, param1); break;
    case MEM_SET: setMem(win, param1, param2); break;
    
    case STATIC_GET: return getStatic(win, param1, param2); break;
    case STATIC_SET: setStatic(win, param1, param2); break;
    
    case COPY: return CopyWindow(win); break;
    default:    break;
    }
}

//分配基類和子類操作函數(shù)的調(diào)用接口
int CallProc(int win, int msg, int param1, int param2) {
    for (int i = 0; i < objectIndex; ++i) { //遍歷所有實例
        if (objects[i].object == win) {     //找到這個實例
            if (objects[i].index == -1)     //如果是基類钞楼,則返回基類對應(yīng)的操作函數(shù)
                return WinProc(win, msg, param1, param2);
            return subclasses[objects[i].index].pFn(win, msg, param1, param2);  //如果是子類喇闸,則返回子類對應(yīng)的操作函數(shù)
        }
    }
    return 0;
}

該項目建立了一個基類window,其中包括一組窗口的位置信息Pos包含xy询件,和窗口的大小信息WinSize包含widthheight燃乍,還有窗口的名字title,是一個 char[200] 數(shù)組(懷念C++的string啊~~~~)

//位置結(jié)構(gòu)體宛琅,包含(x刻蟹,y)
typedef struct Pos {    
    int x, y;
};

//窗口大小結(jié)構(gòu)體,包含寬嘿辟、高
typedef struct WinSize {    
    int width, height;
};

//基類
struct window {
    Pos pos;
    WinSize size;
    char title[200];
};

在這個基類的基礎(chǔ)上舆瘪,用戶可以通過RegisterClass()接口創(chuàng)建子類,子類可以包含附加變量和static變量红伦,在創(chuàng)建時要說明變量類型(即變量所占用字節(jié)數(shù))用于后期分配內(nèi)存英古。

//創(chuàng)建一個新的子類
void RegisterClass(char* name, int data, int staticdata, int (*fn)(int, int, int, int)) {
    strcpy(subclasses[subClassIndex].Name, name);
    subclasses[subClassIndex].Bytes = data;
    subclasses[subClassIndex].StaticBytes = staticdata;
    subclasses[subClassIndex].pStatic = (char*)malloc(staticdata);  //開辟子類的static內(nèi)存空間
    subclasses[subClassIndex].pFn = fn;
    //初始化靜態(tài)變量
    int type;
    switch (staticdata) {
    case 4: *(int*)subclasses[subClassIndex].pStatic = 0; break;        //int初始化為0
    case 1: *(char*)subclasses[subClassIndex].pStatic = 'a'; break;     //char初始化為‘a(chǎn)’
    default:strcpy(subclasses[subClassIndex].pStatic, "");  break;      //string初始化為空串
    }
    subClassIndex++;    //子類的個數(shù)增加1
}

為了儲存子類和實例,分別又建立了兩個結(jié)構(gòu)體SubClassObject昙读,并分別開辟了兩個數(shù)組來儲存子類和實例召调。SubClass結(jié)構(gòu)體中包含了子類的名字、子類附加變量增加字節(jié)數(shù)蛮浑、子類static變量增加字節(jié)數(shù)唠叛、指向static變量的指針和一個函數(shù)指針(這里類似C++中函數(shù)的重載)。Object結(jié)構(gòu)體中儲存了類的實例沮稚,其中包含了指向類的實例的指針和一個表示子類類型的指針玻墅。

//子類
struct SubClass {
    char Name[200]; //子類名字
    int Bytes;      //子類附加變量增加字節(jié)數(shù)
    int StaticBytes;    //子類static變量增加字節(jié)數(shù)
    char* pStatic;      //子類static的指針
    int (*pFn)(int win, int msg, int param1, int param2);   //子類的方法函數(shù)
}subclasses[50];
int subClassIndex = 0;

//獲取當前創(chuàng)建的子類總數(shù)
int getSubClassNum() { return subClassIndex; }

//所有類的實例
struct Object {
    int object; //類的實例
    int index;  //若為基類的實例則是-1,若為子類的實例則為其在subclasses里面對應(yīng)子類的下標
}objects[100];
int objectIndex = 0;    //實例的個數(shù)

//獲取當前創(chuàng)建的實例總數(shù)
int getObjNum() { return objectIndex; }

關(guān)鍵細節(jié)

  1. void* p = malloc(sizeof(window) + subclasses[objects[i].index].Bytes); 開辟子類實例的內(nèi)存空間壮虫。子類實例不僅要開辟基類變量所包含的內(nèi)存空間(實現(xiàn)繼承)澳厢,還要有自己的內(nèi)存空間∏羲疲【注意:子類的實例不包含子類變量的static靜態(tài)變量的內(nèi)存空間剩拢。因為靜態(tài)變量是屬于子類的,在定義子類的時候已經(jīng)開辟饶唤,不屬于子類的實例徐伐。】
  2. window* p = (window*)win; 因為在項目中所有的參數(shù)傳遞都是用指針以int類型進行傳遞募狂,這個語句可以將int(實際上是指針)轉(zhuǎn)換為window類型办素。其他類型的轉(zhuǎn)換同理角雷。
  3. char* p = (char*)win + sizeof(window); 這一步操作本質(zhì)上只是一個指針的跨越,但是它實現(xiàn)了對子類附加變量的指針定位性穿。

不足之處

代碼中有一個暫未解決的bug勺三,本來說是想實現(xiàn)構(gòu)造函數(shù)和析構(gòu)函數(shù),但在 delete 清除實例內(nèi)存的時候出現(xiàn)了一點問題需曾,總是報內(nèi)存泄漏的錯誤吗坚,希望路過的大佬可以幫忙完善一下,不盡感激呆万。

//刪除窗口(暫未通過調(diào)試)
void DestroyWindow(int win) {
    if (!win) {
        delete (window*)win;
    }
}

完整代碼

完整的window.cpp如下:
//Author:SongXingJian 
#include "stdio.h"
#include "string.h"
#include "malloc.h"
#include "window.h"

//位置結(jié)構(gòu)體商源,包含(x,y)
typedef struct Pos {    
    int x, y;
};

//窗口大小結(jié)構(gòu)體谋减,包含寬牡彻、高
typedef struct WinSize {    
    int width, height;
};

//基類
struct window {
    Pos pos;
    WinSize size;
    char title[200];
};

//子類
struct SubClass {
    char Name[200]; //子類名字
    int Bytes;      //子類附加變量增加字節(jié)數(shù)
    int StaticBytes;    //子類static變量增加字節(jié)數(shù)
    char* pStatic;      //子類static的指針
    int (*pFn)(int win, int msg, int param1, int param2);   //子類的方法函數(shù)
}subclasses[50];
int subClassIndex = 0;

//獲取當前創(chuàng)建的子類總數(shù)
int getSubClassNum() { return subClassIndex; }

//所有類的實例
struct Object {
    int object; //類的實例
    int index;  //若為基類的實例則是-1,若為子類的實例則為其在subclasses里面對應(yīng)子類的下標
}objects[100];
int objectIndex = 0;    //實例的個數(shù)

//獲取當前創(chuàng)建的實例總數(shù)
int getObjNum() { return objectIndex; }

//創(chuàng)建一個新的子類
void RegisterClass(char* name, int data, int staticdata, int (*fn)(int, int, int, int)) {
    strcpy(subclasses[subClassIndex].Name, name);
    subclasses[subClassIndex].Bytes = data;
    subclasses[subClassIndex].StaticBytes = staticdata;
    subclasses[subClassIndex].pStatic = (char*)malloc(staticdata);  //開辟子類的static內(nèi)存空間
    subclasses[subClassIndex].pFn = fn;
    //初始化靜態(tài)變量
    int type;
    switch (staticdata) {
    case 4: *(int*)subclasses[subClassIndex].pStatic = 0; break;        //int初始化為0
    case 1: *(char*)subclasses[subClassIndex].pStatic = 'a'; break;     //char初始化為‘a(chǎn)’
    default:strcpy(subclasses[subClassIndex].pStatic, "");  break;      //string初始化為空串
    }
    subClassIndex++;    //子類的個數(shù)增加1
}

//移動窗口
void move(int win, int deltaX, int deltaY) {
    window* p = (window*)win;   //將任意封裝類型強制轉(zhuǎn)化為所需要的內(nèi)容
    p->pos.x += deltaX;
    p->pos.y += deltaY;
}

//設(shè)置窗口位置
void SetPosition(int win, int x, int y) {
    window* p = (window*)win;
    p->pos.x = x;
    p->pos.y = y;
}

//返回窗口位置
Pos GetPosition(int win) {
    window* p = (window*)win;
    Pos win_pos;
    win_pos.x = p->pos.x;
    win_pos.y = p->pos.y;
    return win_pos;
}

//設(shè)置窗口寬和高
void SetSize(int win, int width, int height) {
    window* p = (window*)win;
    p->size.width = width;
    p->size.height = height;
}

//獲取窗口寬和高
WinSize GetSize(int win) {
    window* p = (window*)win;
    WinSize win_size;
    win_size.width = p->size.width;
    win_size.height = p->size.height;
    return win_size;
}

//設(shè)置窗口title
void SetTitle(int win, char* newTitle) {
    window* p = (window*)win;
    //p->title = newTitle;
    strcpy(p->title, newTitle);
}

//返回窗口title
char* GetTitle(int win) {
    window* p = (window*)win;
    return p->title;
}

//創(chuàng)建Window出爹,參數(shù)是子類名字讨便,創(chuàng)建基類則傳入0
int CreateWindow(char* name) {
    int new_win = 0;
    if (!name) {    //創(chuàng)建基類實例
        window* p = (window*)malloc(sizeof(window));
        WinProc((int)p, CONSTRUCT, 0, 0);   //初始化基類變量
        new_win = (int)p;
        objects[objectIndex].object = new_win;
        objects[objectIndex].index = -1;    //基類的下標設(shè)置為-1
        objectIndex++;  //實例數(shù)+1
    }
    else {  //創(chuàng)建子類實例
        for (int j = 0; j < subClassIndex; ++j) {
            if (!strcmp(name, subclasses[j].Name)) {    //如果name相等,即找到了subclasses的位置
                void* p = malloc(sizeof(window) + subclasses[j].Bytes); //開辟該子類實例所需空間
                WinProc((int)p, CONSTRUCT, 0, 0);   //初始化基類變量
                new_win = (int)p;
                objects[objectIndex].object = new_win;
                objects[objectIndex].index = j; //下標設(shè)置為在subclasses里面相同子類的下標
                objectIndex++;  //實例數(shù)+1
                break;
            }
        }
    }   
    return new_win;
}

//基類的構(gòu)造函數(shù),初始化基類變量
int ConstructBase(int win) {
    window* p = (window*)win;
    strcpy(p->title, "");
    p->pos.x = 0;
    p->pos.y = 0;
    p->size.width = 0;
    p->size.height = 0;
    return (int)p;
}

//拷貝并創(chuàng)建實例
int CopyWindow(int win) {
    int new_win;
    for (int i = 0; i < objectIndex; ++i) { //遍歷所有實例
        if (objects[i].object == win) {     //找到這個實例
            if (objects[i].index != -1) {   //如果是子類
                void* p = malloc(sizeof(window) + subclasses[objects[i].index].Bytes);  //開辟該子類實例所需空間               
                new_win = (int)p;
                WinProc(new_win, CONSTRUCT, 0, 0);
                //確定子類附加變量的參數(shù)類型
                int type_mem;
                if (subclasses[objects[i].index].Bytes == 4)    type_mem = SUB_INT;
                else if (subclasses[objects[i].index].Bytes == 1)   type_mem = SUB_CHAR;
                else type_mem = SUB_STRING;
                //復(fù)制子類附加變量
                WinProc(new_win, MEM_SET, type_mem, WinProc(objects[i].object, MEM_GET, type_mem, 0));
                objects[objectIndex].object = new_win;
                objects[objectIndex].index = objects[i].index;  //下標設(shè)置為在subclasses里面相同子類的下標
                objectIndex++;  //實例數(shù)+1
            }
            else {  //如果是基類
                window* p = (window*)malloc(sizeof(window));
                new_win = (int)p;
                WinProc(new_win, CONSTRUCT, 0, 0);
                objects[objectIndex].object = new_win;
                objects[objectIndex].index = -1;    //基類的下標設(shè)置為-1
                objectIndex++;  //實例數(shù)+1
            }
            //復(fù)制基類變量
            WinProc(new_win, SET_TITLE, WinProc(objects[i].object, GET_TITLE, 0, 0), 0);    //賦值新實例的title
            Pos w_pos = *(Pos*)WinProc(objects[i].object, GET_POSITION, 0, 0);  //獲取被復(fù)制實例的pos
            WinProc(new_win, SET_POSITION, w_pos.x, w_pos.y);   //賦值新實例的pos
            WinSize w_size = *(WinSize*)WinProc(objects[i].object, GET_SIZE, 0, 0); //獲取被復(fù)制實例的size
            WinProc(new_win, SET_SIZE, w_size.width, w_size.height);    //賦值新實例的size

            return new_win;
        }
    }
}

//刪除窗口(暫未通過調(diào)試)
void DestroyWindow(int win) {
    if (!win) {
        delete (window*)win;
    }
}

//打印窗口的所有屬性
void PrintWindow(int win) {
    window* p = (window*)win;
    printf_s("\n================ %s ================\nPosition: (%d, %d)\nWidth: %d\tHeight: %d\n", p->title, p->pos.x, p->pos.y, p->size.width, p->size.height);
}

//獲得子類中的變量
int getMem(int win, int  sub_type) {
    char* p = (char*)win + sizeof(window);  //指針p跨越基類內(nèi)存以政,指向子類附加內(nèi)存
    if (sub_type == SUB_INT)            //子類附加的數(shù)據(jù)是int
        return *(int*)p;
    else if (sub_type == SUB_CHAR)  //子類附加的數(shù)據(jù)是char
        return *p;
    else if (sub_type == SUB_STRING)    //子類附加的數(shù)據(jù)是字符串
        return (int)p;
}

//設(shè)置子類中的變量
void setMem(int win, int  sub_type, int param2) {
    char* p = (char*)win + sizeof(window);  //指針p跨越基類內(nèi)存霸褒,指向子類附加內(nèi)存
    if (sub_type == SUB_INT)    //子類附加的數(shù)據(jù)是int
        *(int*)p = param2;
    else if (sub_type == SUB_CHAR)  //子類附加的數(shù)據(jù)是char
        *p = param2;
    else if (sub_type == SUB_STRING)    //子類附加的數(shù)據(jù)是字符串
        strcpy(p, (char*)param2);
}

//獲得子類中的static變量
int getStatic(int win, int  sub_type, int param2) {
    char* p = 0;
    for (int i = 0; i < objectIndex; ++i) { //遍歷所有實例
        if (objects[i].object == win) {     //找到這個實例
            if (objects[i].index != -1)     //如果不是基類
                p = subclasses[objects[i].index].pStatic;
            break;
        }
    }
    if (sub_type == SUB_INT)    //子類static變量是int
        return *(int*)p;
    else if (sub_type == SUB_CHAR)  //子類static變量是char
        return *p;
    else if (sub_type == SUB_STRING)    //子類static變量是字符串
        return (int)p;
}

//設(shè)置子類的static變量
void setStatic(int win, int  sub_type, int param2) {
    char* p = 0;
    for (int i = 0; i < objectIndex; ++i) { //遍歷所有實例
        if (objects[i].object == win) {     //找到這個實例對應(yīng)的子類
            if (objects[i].index != -1) {
                p = subclasses[objects[i].index].pStatic;
                if (sub_type == SUB_INT)
                    *(int*)p = param2;
                else if (sub_type == SUB_CHAR)
                    *p = param2;
                else if (sub_type == SUB_STRING) 
                    strcpy(p, (char*)param2);
                break;
            }
        }
    }

}

//封裝的窗口操作函數(shù)
int WinProc(int win, int msg, int param1, int param2) {
    switch (msg){
    case MOVE: move(win, param1, param2); break;
    case SET_POSITION:  SetPosition(win, param1, param2); break;
    case GET_POSITION: {Pos p = GetPosition(win);   return (int)&p; }break;
    
    case SET_SIZE: SetSize(win, param1, param2); break;
    case GET_SIZE: {WinSize p = GetSize(win);   return (int)&p; }break;
    
    case SET_TITLE: SetTitle(win, (char*)param1); break;
    case GET_TITLE: return (int)GetTitle(win); break;
    
    case PRINTWINDOW: PrintWindow(win); break;
    
    case CONSTRUCT: return ConstructBase(win); break;
    case DESTRACT: DestroyWindow(win); break;
    
    case MEM_GET: return getMem(win, param1); break;
    case MEM_SET: setMem(win, param1, param2); break;
    
    case STATIC_GET: return getStatic(win, param1, param2); break;
    case STATIC_SET: setStatic(win, param1, param2); break;
    
    case COPY: return CopyWindow(win); break;
    default:    break;
    }
}

//分配基類和子類操作函數(shù)的調(diào)用接口
int CallProc(int win, int msg, int param1, int param2) {
    for (int i = 0; i < objectIndex; ++i) { //遍歷所有實例
        if (objects[i].object == win) {     //找到這個實例
            if (objects[i].index == -1)     //如果是基類,則返回基類對應(yīng)的操作函數(shù)
                return WinProc(win, msg, param1, param2);
            return subclasses[objects[i].index].pFn(win, msg, param1, param2);  //如果是子類盈蛮,則返回子類對應(yīng)的操作函數(shù)
        }
    }
    return 0;
}
完整的window.h如下:
//Author:SongXingJian

#define MOVE 1
#define SET_POSITION 2
#define GET_POSITION 3
#define SET_SIZE 4
#define GET_SIZE 5
#define SET_TITLE 6
#define GET_TITLE 7
#define PRINTWINDOW 8

#define CONSTRUCT 9
#define DESTRACT 10     //暫未通過調(diào)試

#define MEM_GET 11
#define MEM_SET 12

#define STATIC_GET 13
#define STATIC_SET 14

#define SUB_INT 15
#define SUB_CHAR 16
#define SUB_STRING 17

#define COPY 18


int getSubClassNum();   //獲取當前創(chuàng)建的子類總數(shù)
int getObjNum();        //獲取當前創(chuàng)建的實例總數(shù)
int CreateWindow(char* name);   //創(chuàng)建實例废菱,參數(shù)是子類名字,基類則傳入0
int WinProc(int win, int msg, int param1, int param2);      //SDK整體封裝
int CallProc(int win, int msg, int param1, int param2);     //多態(tài)
void RegisterClass(char* name, int data, int staticdata, int (*fn)(int, int, int, int));    //定義一個新的子類


/*  封裝過程
//void move(window* win, int deltaX, int deltaY);
//void move(void* win, int deltaX, int deltaY);
void move(int win, int deltaX, int deltaY); //對外提供接口
struct Pos GetPosition(int win);
void Size(int win, int newX, int newY);
void SetWindowText(int win, char* newTitle);
char* GetWindowText(int win);
*/
完整的main_test.cpp(主函數(shù))如下:
//Author:SongXingJian
#include "window.h"
#include "stdio.h"

//win_num子類的函數(shù)
int sub_window_num(int win, int msg, int param1, int param2) {
    switch (msg){
        //子類構(gòu)造函數(shù)抖誉,創(chuàng)建一個子類
    case CONSTRUCT: {   
        int w = CreateWindow((char*)win);
        WinProc(w, SET_TITLE, param1, 0);   //初始化title
        WinProc(w, MEM_SET, SUB_INT, 0);    //初始化子類實例附加變量為0
        return w;
    }break;
        //設(shè)置子類實例附加變量
    case MEM_SET: {
        printf("Set the num: %d ---> %d\n", WinProc(win, MEM_GET, SUB_INT, 0), param2); //展示修改前--->修改后
        WinProc(win, msg, SUB_INT, param2);
    }break;
        //獲取子類實例附加變量
    case MEM_GET: {
        int p = WinProc(win, msg, SUB_INT, 0);
        printf("Num: %d\n", p);
    }break;
        //設(shè)置子類static變量
    case STATIC_SET: {
        printf("Set the static: %d ---> %d\n", WinProc(win, STATIC_GET, SUB_INT, 0), param2);   //展示修改前--->修改后
        WinProc(win, msg, SUB_INT, param2);
    }break;
        //獲取子類static變量
    case STATIC_GET: {
        int p = WinProc(win, msg, SUB_INT, 0);
        printf("Static: %d\n", p);
    }break;
        //打印子類實例的所有變量
    case PRINTWINDOW: {
        WinProc(win, msg, param1, param2);
        printf("Num: %d\t\tStatic: %d\n", WinProc(win, MEM_GET, SUB_INT, 0), WinProc(win, STATIC_GET, SUB_INT, 0));
    }break;

    default:return WinProc(win, msg, param1, param2); break;
    }
}

//win_c子類的函數(shù)
int sub_window_c(int win, int msg, int param1, int param2) {
    switch (msg) {
        //子類構(gòu)造函數(shù)殊轴,創(chuàng)建一個子類
    case CONSTRUCT: {
        int w = CreateWindow((char*)win);
        WinProc(w, SET_TITLE, param1, 0);   //初始化title
        WinProc(w, MEM_SET, SUB_CHAR, (int)'A');    //初始化子類實例附加變量為'A'
        return w;
    }break;
        //設(shè)置子類實例附加變量
    case MEM_SET: {
        printf("Set the Char: %c ---> %c\n", WinProc(win, MEM_GET, SUB_CHAR, 0), (char)param2); //展示修改前--->修改后
        WinProc(win, msg, SUB_CHAR, param2);
    }break;
        //獲取子類實例附加變量
    case MEM_GET: {
        int p = WinProc(win, msg, SUB_CHAR, 0);
        printf("Char: %c\n", (char)p);
    }break;
        //設(shè)置子類static變量
    case STATIC_SET: {
        printf("Set the static: %c ---> %c\n", (char)WinProc(win, STATIC_GET, SUB_CHAR, 0), (char)param2);  //展示修改前--->修改后
        WinProc(win, msg, SUB_CHAR, param2);
    }break;
        //獲取子類static變量
    case STATIC_GET: {
        int p = WinProc(win, msg, SUB_CHAR, 0);
        printf("Static: %c\n", (char)p);
    }break;
        //打印子類實例的所有變量
    case PRINTWINDOW: {
        WinProc(win, msg, param1, param2);
        printf("Char: %c\t\tStatic: %c\n", WinProc(win, MEM_GET, SUB_CHAR, 0), WinProc(win, STATIC_GET, SUB_CHAR, 0));
    }break;

    default:return WinProc(win, msg, param1, param2); break;
    }
}

int main() {
    char win_num[] = "sub_win_num";
    char win_c[] = "sub_win_c";

    char win_num_obj[] = "sub_win_num_obj";
    char win_c_obj[] = "sub_win_c_obj";
    char win_base_obj[] = "base_win_obj";
    
    /****************** 創(chuàng)建win_num子類 ******************/
    RegisterClass(win_num, sizeof(int), sizeof(int), sub_window_num);
    //int sub_w = CreateWindow(win_num);
    int sub_w = sub_window_num((int)win_num, CONSTRUCT, (int)win_num_obj, 0);   // 構(gòu)造函數(shù),可以創(chuàng)建實例袒炉,并初始化title旁理、基類變量和實例附加變量 
    CallProc(sub_w, MEM_SET, SUB_INT, 5);       //設(shè)置實例的子類附加變量
    CallProc(sub_w, MEM_GET, SUB_INT, 0);
    CallProc(sub_w, STATIC_SET, SUB_INT, 3);    //設(shè)置實例所屬子類static變量
    CallProc(sub_w, STATIC_GET, SUB_INT, 0);
    CallProc(sub_w, PRINTWINDOW, 0, 0);         //打印窗口屬性
    //復(fù)制這個實例
    int sub_w_copy = CallProc(sub_w, COPY, 0, 0);
    CallProc(sub_w_copy, PRINTWINDOW, 0, 0);    //打印窗口屬性
    //驗證子類static變量的性質(zhì)
    printf("\n\n****** 驗證子類static變量的性質(zhì) ******\n");
    CallProc(sub_w_copy, STATIC_SET, SUB_INT, 100); //通過復(fù)制的實例修改靜態(tài)變量
    CallProc(sub_w, STATIC_GET, SUB_INT, 0);        //通過另一個實例調(diào)用
    printf("\n****** The total number of Objects: %d ******\n\n", getObjNum());


    /****************** 創(chuàng)建win_c子類 ******************/
    RegisterClass(win_c, sizeof(char), sizeof(char), sub_window_c);
    int sub_w_c = sub_window_c((int)win_c, CONSTRUCT, (int)win_c_obj, 0);   // 構(gòu)造函數(shù),可以創(chuàng)建實例我磁,并初始化title孽文、基類變量和實例附加變量 
    CallProc(sub_w_c, MEM_SET, SUB_CHAR, (int)'B');     //設(shè)置實例的子類附加變量
    CallProc(sub_w_c, MEM_GET, SUB_CHAR, 0);
    CallProc(sub_w_c, STATIC_SET, SUB_CHAR, (int)'S');  //設(shè)置實例所屬子類static變量
    CallProc(sub_w_c, STATIC_GET, SUB_CHAR, 0);
    CallProc(sub_w_c, PRINTWINDOW, 0, 0);               //打印窗口屬性
    //復(fù)制這個實例
    int sub_w_c_copy = CallProc(sub_w_c, COPY, 0, 0);
    CallProc(sub_w_c_copy, PRINTWINDOW, 0, 0);
    printf("\n\n****** The total number of Objects: %d ******\n\n", getObjNum());
    printf("\n****** The total number of SubClasses: %d ******\n\n", getSubClassNum());


    /****************** 創(chuàng)建基類 ******************/
    int base_w = CreateWindow(0);
    CallProc(base_w, PRINTWINDOW, 0, 0);    //打印初始化的基類
    CallProc(base_w, SET_TITLE, (int)win_base_obj, 0);  //窗口重命名
    CallProc(base_w, SET_POSITION, 3, 4);   //設(shè)置窗口位置
    CallProc(base_w, MOVE, 2, 2);           //移動窗口
    CallProc(base_w, SET_SIZE, 5, 5);       //設(shè)置窗口大小
    CallProc(base_w, PRINTWINDOW, 0, 0);    //打印窗口屬性
    printf("\n****** The total number of Objects: %d ******\n\n", getObjNum());

    return 0;
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市夺艰,隨后出現(xiàn)的幾起案子芋哭,更是在濱河造成了極大的恐慌,老刑警劉巖郁副,帶你破解...
    沈念sama閱讀 222,865評論 6 518
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件减牺,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機拔疚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,296評論 3 399
  • 文/潘曉璐 我一進店門肥隆,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人稚失,你說我怎么就攤上這事栋艳。” “怎么了墩虹?”我有些...
    開封第一講書人閱讀 169,631評論 0 364
  • 文/不壞的土叔 我叫張陵,是天一觀的道長憨琳。 經(jīng)常有香客問我诫钓,道長,這世上最難降的妖魔是什么篙螟? 我笑而不...
    開封第一講書人閱讀 60,199評論 1 300
  • 正文 為了忘掉前任菌湃,我火速辦了婚禮,結(jié)果婚禮上遍略,老公的妹妹穿的比我還像新娘惧所。我一直安慰自己,他們只是感情好绪杏,可當我...
    茶點故事閱讀 69,196評論 6 398
  • 文/花漫 我一把揭開白布下愈。 她就那樣靜靜地躺著,像睡著了一般蕾久。 火紅的嫁衣襯著肌膚如雪势似。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,793評論 1 314
  • 那天僧著,我揣著相機與錄音履因,去河邊找鬼。 笑死盹愚,一個胖子當著我的面吹牛栅迄,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播皆怕,決...
    沈念sama閱讀 41,221評論 3 423
  • 文/蒼蘭香墨 我猛地睜開眼毅舆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了愈腾?” 一聲冷哼從身側(cè)響起朗兵,我...
    開封第一講書人閱讀 40,174評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎顶滩,沒想到半個月后余掖,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,699評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,770評論 3 343
  • 正文 我和宋清朗相戀三年盐欺,在試婚紗的時候發(fā)現(xiàn)自己被綠了赁豆。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,918評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡冗美,死狀恐怖魔种,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情粉洼,我是刑警寧澤节预,帶...
    沈念sama閱讀 36,573評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站属韧,受9級特大地震影響安拟,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜宵喂,卻給世界環(huán)境...
    茶點故事閱讀 42,255評論 3 336
  • 文/蒙蒙 一糠赦、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧锅棕,春花似錦拙泽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,749評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至德绿,卻和暖如春朋其,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背脆炎。 一陣腳步聲響...
    開封第一講書人閱讀 33,862評論 1 274
  • 我被黑心中介騙來泰國打工梅猿, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人秒裕。 一個月前我還...
    沈念sama閱讀 49,364評論 3 379
  • 正文 我出身青樓袱蚓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親几蜻。 傳聞我的和親對象是個殘疾皇子喇潘,可洞房花燭夜當晚...
    茶點故事閱讀 45,926評論 2 361

推薦閱讀更多精彩內(nèi)容