デザインパターンは一般的にオブジェクト指向プログラミングに関連するものであることを私は知っていますが、Cをプログラミングするときによく使用するパターンはありますか?
私は古典的なOOパターンの単純な翻訳には興味がなく、Duffのデバイスについては言及しないでください。;-)
回答:
私のお気に入りは、AdamTornhillによる「PatternsinC」シリーズです。
また、私はいつもgoto
デコレータパターンのための素晴らしい貧乏人の道具だと思っています。
更新:cを使用する必要がある場合を除いて、CではなくRust(rust-lang.org)を使用することを強くお勧めします。Rustには、速度やcとのバイナリライブラリの互換性など、cのすべての利点がありますが、コンパイラは複雑さの多くを処理して、コードがメモリセーフであり、データの競合がないことを確認します。また、移植性があり、一般的なタスク用の標準ライブラリがあり、さまざまなデザインパターン用にプログラミングするのがはるかに簡単です。
デザインパターンは、言語機能が欠落していると見なされる可能性があります。デザインパターンの導入:再利用可能なオブジェクト指向ソフトウェアの要素は次のように述べています。
プログラミング言語の選択は、自分の視点に影響を与えるため重要です。私たちのパターンはSmalltalk / C ++レベルの言語機能を想定しており、その選択によって、簡単に実装できるものとできないものが決まります。手続き型言語を想定した場合、「継承」、「カプセル化」、「ポリモーフィズム」と呼ばれる設計パターンが含まれている可能性があります。同様に、私たちのパターンのいくつかは、あまり一般的ではないオブジェクト指向言語によって直接サポートされています。CLOSには、たとえば、Visitorなどのパターンの必要性を減らす複数のメソッドがあります。(斜体の鉱山)
イタリック体の文はあなたの質問への答えです。
標準ライブラリのqsort
関数など、コールバックを介したポリモーフィズム。必要なのは2つの要素を比較する方法だけで、それらの配列を並べ替えることができます。
関数のセット(vtables)を使用して型の関連するプロパティを表すことにより、これよりもはるかに洗練されたものになり、汎用ルーチンがそれを便利に処理できるようになります。たとえば、開いているファイルまたはネットワークポートに対する読み取り、書き込みなどの呼び出し。
はい、あります。レイジー初期化、シングルトン、オブジェクトプール、オブジェクト状態などは、純粋なCで簡単に実装できます。
例(遅延初期化)
#include <stdio.h>
struct foo
{
int payload;
};
int calculate_payload()
{
printf("%s\n", "Performing lengthy initialization...");
return 42;
}
struct foo *get_default_foo()
{
static int foo_calculated = 0;
static struct foo default_foo;
if (!foo_calculated) /* assuming single-threaded access */
{
foo_calculated = 1;
default_foo.payload = calculate_payload();
}
return &default_foo;
}
int main()
{
struct foo *foo1, *foo2;
printf("%s\n", "Starting the program");
foo1 = get_default_foo();
printf("%d\n", foo1->payload);
foo2 = get_default_foo();
printf("%d\n", foo2->payload);
return 0;
}
頭のてっぺんから
goto
デコレータとの関係について詳しく教えてください。