现在的位置: 首页 > 综合 > 正文

C语言模拟虚基类 – 模拟lighttpd fdevent实现

2013年06月26日 ⁄ 综合 ⁄ 共 2998字 ⁄ 字号 评论关闭

看了lighttpd中的fdevent的实现过程有些巧妙,写个例子模拟它的的实现:

虚基类是fdos(os操作系统,fd是随便加的没什么意义),它有三个派生类分别是:windows, linux, mac,

它们的都有的public方法是:open, close, playgame。

/// fdos.h

#ifndef FDOS_H_INCLUDED
#define FDOS_H_INCLUDED

typedef enum
{
    OS_UNSET = -1,
    OS_WINDOWS,
    OS_LINUX,
    OS_MAC
}fd_type;

typedef struct fdos
{
    fd_type type;
    int maxfds;

    int (*open)(struct fdos *os);
    void (*close)(struct fdos *os);
    void (*playgame)(struct fdos *os, char *name);
}fdos;

// public
fdos* fdos_init(fd_type type, int maxfds);
void fdos_free(fdos *os);

int fdos_open(fdos *os);
void fdos_close(fdos *os);
void fdos_playgame(fdos *os, char *name);

// private
int fdos_windows_init(fdos *os);
int fdos_linux_init(fdos *os);
int fdos_mac_init(fdos *os);

#endif // FDOS_H_INCLUDED

/// fdos.cpp

#include "fdos.h"
#include <stdio.h>
#include <stdlib.h>

fdos* fdos_init(fd_type type, int maxfds)
{
    fdos *os;

    os = (fdos*)malloc(sizeof(*os));
    os->maxfds = maxfds;

    switch (type)
    {
        case OS_WINDOWS:
        if (0 != fdos_windows_init(os))
        {
            printf("windows init fail\n");
            return NULL;
        }
        return os;

        case OS_LINUX:
        if (0 != fdos_linux_init(os))
        {
            printf("linux init fail\n");
            return NULL;
        }
        return os;

        case OS_MAC:
        if (0 != fdos_mac_init(os))
        {
            printf("mac init fail\n");
            return NULL;
        }
        return os;

        case OS_UNSET:
        break;
    }

    printf("fdos init fail\n");
    return NULL;
}

void fdos_free(fdos *os)
{
    if (os)
    {
        free(os);
    }
}

int fdos_open(fdos *os)
{
    return os->open(os);
}

void fdos_close(fdos *os)
{
    return os->close(os);
}

void fdos_playgame(fdos *os, char *name)
{
    return os->playgame(os, name);
}

/// fdwindows.cpp

#include "fdos.h"
#include <stdio.h>

static int fdos_windows_open(fdos *os)
{
    printf("windows open\n");
    return 0;
}

static void fdos_windows_close(fdos *os)
{
    printf("windows close\n");
}

static void fdos_windows_playgame(fdos *os, char *name)
{
    printf("windows playgame: %s\n", name);
}

int fdos_windows_init(fdos *os)
{
    os->type = OS_WINDOWS;
    // x作为宏参数,##x则表示连接宏参数
    // 如果是#x, 则表示是一个字符串,如:
    // #define MY_CONST(x) #x
    // printf("%s", MY_CONST(hello));
    // 输出:hello
#define SET(x) \
    os->x = fdos_windows_##x;

    // 相当于:fdos_windows_open
    SET(open);
    // 相当于:fdos_windows_close
    SET(close);
    // 相当于:fdos_windows_playgame
    SET(playgame);

    return 0;
}

/// fdlinux.cpp

#include "fdos.h"
#include <stdio.h>

static int fdos_linux_open(fdos *os)
{
    printf("linux open\n");
    return 0;
}

static void fdos_linux_close(fdos *os)
{
    printf("linux close\n");
}

static void fdos_linux_playgame(fdos *os, char *name)
{
    printf("linux playgame: %s\n", name);
}

int fdos_linux_init(fdos *os)
{
    os->type = OS_LINUX;
#define SET(x) \
    os->x = fdos_linux_##x;

    SET(open);
    SET(close);
    SET(playgame);

    return 0;
}

/// fdmac.cpp

#include "fdos.h"
#include <stdio.h>

static int fdos_mac_open(fdos *os)
{
    printf("mac open\n");
    return 0;
}

static void fdos_mac_close(fdos *os)
{
    printf("mac close\n");
}

static void fdos_mac_playgame(fdos *os, char *name)
{
    printf("mac playgame: %s\n", name);
}

int fdos_mac_init(fdos *os)
{
    os->type = OS_MAC;
#define SET(x) \
    os->x = fdos_mac_##x;

    SET(open);
    SET(close);
    SET(playgame);

    return 0;
}

/// main.cpp

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "fdos.h"

/// test
int main(void)
{
    fdos *os = fdos_init(OS_WINDOWS, 3);
    fdos_open(os);
    fdos_playgame(os, "wow");
    fdos_close(os);
    fdos_free(os);

    os = fdos_init(OS_LINUX, 3);
    fdos_open(os);
    fdos_free(os);

    os = fdos_init(OS_MAC, 3);
    fdos_playgame(os, "zx");
    fdos_free(os);

    return 0;
}

抱歉!评论已关闭.