1

似乎 ANSI C 中的 OO 不是当今流行的 OO 方法。有谁知道使用严格的 ANSI C 编写简单设计模式的方法,以便我可以向朋友证明这是可能的?(Axel-Tobias Schreiners 的书让我继续这样做!)

4

2 回答 2

1

使用 C 的 OO 确实可以使用函数指针来实现,正如这个 SO question中很好解释的那样。

使用该帖子中的信息,这是我将如何使用基本继承在 C 中实现策略模式的方法。

让我们使用以下 C++ 作为指南:

class StrategyBase
{
    ...
    StrategyBase();
    virtual void strategyMethod() = 0;
    ...
};

class StrategyDerived
{
    ...
    StrategyDerived();
    void strategyMethod();
    ...
};

这是相应的C代码:

typedef struct StrategyBase_t StrategyBase;
struct StrategyBase_t
{
    StrategyBase *base; /* must be first memeber */
    void (*strategyMethod)(const void *self);
};
StrategyBase *newStrategyBase();
void strategyMethod(const void *self);  /* the abstract method */

struct StrategyDerived
{
    StrategyBase *base; /* must be first memeber */
    void (*strategyMethod)(const void *self);
    /* more derived attributes here */
};
typedef struct StrategyDerived_t StrategyDerived;
StrategyDerived *newStrategyDerived();

以下是功能实现:

void strategyMethod(const void *self)
{
    /* If called with just a StrategyBase, strategyMethod will be NULL, *
     * so perhaps some sort of protection should be added here first    */
    ((StrategyBase*) self)->base->strategyMethod();
}

void strategyMethodDerived(const void *self)
{
    /* Put your implementation here */
}

/* StrategyBase constructor */
StrategyBase *newStrategyBase()
{
    StrategyBase *self = (StrategyBase*) malloc(sizeof(StrategyBase));
    self->base = self; /* See comment below about virtual table */
    self->strategyMethod = NULL; /* StrategyBase is abstract, right? */
    return self;
}

/* StrategyDerived constructor */
StrategyDerived *newStrategyDerived()
{
    StrategyDerived *self = (StrategyDerived*) malloc(sizeof(StrategyDerived));
    self->base = newStrategyBase();
    self->strategyMethod = self->base->strategyMethod = strategyMethodDerived;
    return self;
}

虚拟表实现是非常基本的,但应该可以工作。理想情况下,应该实现一些更强大的东西。

然后你只需要在需要策略的 Struct 中使用指向 StrategyBase 的指针,并且你有一个用 C 实现的策略模式。我没有尝试编译它,但这应该是一个很好的起点。

于 2012-05-21T07:19:17.543 回答
0

没什么。而不是 class Foo,使用 a struct foo; 而不是构造函数Foo::Foo(...),有一个函数struct foo *foo_new(...)

有关真实示例,请参阅古老的GObject 库

于 2012-05-20T23:44:05.080 回答