ANSI CのOOは、今日のOOへの好ましいアプローチではないようです。厳密なANSICを使用して単純なデザインパターンをコーディングする方法を知っている人はいますか?それが可能であることを友人に証明できますか?(Axel-Tobias Schreinersの本は私にこれを続けさせました!)
質問する
446 次
2 に答える
1
このSOの質問で非常によく説明されているように、Cを使用するOOは、実際に関数ポインターを使用して実装できます。
その投稿からの情報を使用して、基本的な継承を使用して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
それには何もありません。クラスの代わりに、 ;Foo
を使用します。struct foo
コンストラクターの代わりにFoo::Foo(...)
、関数がありますstruct foo *foo_new(...)
。
実際の例については、由緒あるGObjectライブラリを参照してください。
于 2012-05-20T23:44:05.080 に答える