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