1

ANSI CのOOは、今日のOOへの好ましいアプローチではないようです。厳密なANSICを使用して単純なデザインパターンをコーディングする方法を知っている人はいますか?それが可能であることを友人に証明できますか?(Axel-Tobias Schreinersの本は私にこれを続けさせました!)

4

2 に答える 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 に答える