私は特に、Pythonなどのインタープリタ言語のコアを形成するオブジェクトの実装とは対照的に、C内から使用されることを意図したオブジェクトに興味があります。人々はCでオブジェクトを構築するためにどのような手法や戦略を使用しますか(C++ではありません)?
答えて
GObjectのようなライブラリ。
基本的に、GObjectは、不透明な値(整数、文字列)とオブジェクトを記述する一般的な方法を提供します(インタフェースを手作業で記述することにより、関数ポインタの構造としてC++のVTableに基本的に対応します)。あなたは、多くの場合、また、手実装してのvtableをIJG's実装で"COM in plain C"
EFraim - 回答にGObject実装戦略を記述して、他の解決策のいくつかと比較することはできますか? – SetJmp
私はこのような何かする傾向がある:
:FOOを使用するコードでは、次にstatic void plugh(struct foo *, ...) { ... }
static void blah(struct foo *, ...) { ... }
static struct foo_ops foo_ops = { blah, plugh };
struct foo *new_foo(...) {
struct foo *foop = malloc(sizeof(*foop));
foop->ops = &foo_ops;
/* fill in rest of *foop */
return foop;
}
:これらの構造体の定義では
struct foo_ops {
void (*blah)(struct foo *, ...);
void (*plugh)(struct foo *, ...);
};
struct foo {
struct foo_ops *ops;
/* data fields for foo go here */
};
を、コードの実装fooは次のようになります
struct foo *foop = new_foo(...);
foop->ops->blah(foop, ...);
foop->ops->plugh(foop, ...);
このコードは、マクロまたはインライン関数で整理することができるので、Cのように見える
foo_blah(foop, ...);
foo_plugh(foop, ...);
あなたが「OPS」フィールドのための合理的に短い名前に固執する場合、単に元々示されたコードを書くことが特に冗長ではありません。
この手法は、Cで比較的単純なオブジェクトベースの設計を実装するには完全に適していますが、ではなく、では明示的にクラスを表す方法やメソッドの継承などを処理します。そのためには、GObjectのようなものが必要かもしれませんが、より複雑なフレームワークの余分な機能が本当に必要であることを確認することをお勧めします。
"オブジェクト"という用語の使用は少し曖昧ですので、私はあなたがオブジェクト指向プログラミングの特定の側面を達成するためにCを使う方法を尋ねていると思います。)
方法多型:
メソッドの多型は、典型的には、関数ポインタを使用してCでエミュレートされます。例えば、私は私がimage_scaler(画像を取り込み、新しい次元にそれをリサイズし、何かを)表すために使用される構造体を持っていた場合、私はこのような何かを行うことができます:
struct image_scaler {
//member variables
int (*scale)(int, int, int*);
}
その後、私はいくつかの画像スケーラを作ることができます以下のような:
struct image_scaler nn, bilinear;
nn->scale = &nearest_neighbor_scale;
bilinear->scale = &bilinear_scale;
これは私がimage_scalerに取り、それは単にそれに異なるimage_scalerを渡すことによって、スケールの方法だ使用する任意の機能のための多型動作を実現することができます。
継承
継承は、通常のような達成される:
struct base{
int x;
int y;
}
struct derived{
struct base;
int z;
}
は今、私はベースのすべての「継承された」フィールドの取得に伴い、の派生余分なフィールドを使用して自由です。さらに、構造体ベースのみを取り入れる関数がある場合。構造体derviedポインタを構造体の基本ポインタにキャストするだけで済みます。
ありがとうFalain(私はupvoted)。これを行うライブラリを指すことができますか?私や他の誰かが実装全体を調べることができますか? – SetJmp
Daleのアプローチと似ていますが、PostgreSQLが内部的に構文木ノードや式の型などを表現する方法があります。デフォルトNode
とExpr
構造体はNodeTag
は、unsigned int型のtypedefである
typedef struct {
NodeTag n;
} Node;
の線に沿って、があり、そしてすべての可能なノードタイプを記述する定数の束とヘッダファイルがあります。ノード自体は次のようになります。
typedef struct {
NodeTag n = FOO_NODE;
/* other members go here */
} FooNode;
とFooNode
があるため、Cの構造体の癖で、大手を振ってNode
にキャストすることができます:2つの構造体は、同一の第1のメンバーを持っている場合、彼らはお互いにキャストすることができます。
はい、これはFooNode
をBarNode
にキャストすることができますが、これはおそらくやりたくないことを意味します。適切な実行時の型チェックが必要な場合は、GObjectを使用することができます。
長い間ずっと前(1988年頃)私はCコンパイラを使っていましたが、パースノードは個々のノードタイプのビットユニオンであり、ユニオンのどの枝が有効であるかを決めるためにユニオンの外側にタイプタグがあります。あなたは説明します。今日、私はほぼ確実に上記の私の提案のラインに沿ってそれを行うでしょう。私は関数ポインタを使用すると、呼び出し側が呼び出す関数の名前を知らないので、目的のパブリックAPIを定義する必要があることがわかります。実装に関する内部データを使用するために関数を通過するのは非常に難しいです。 –
Sigh ... s/bit union/big union /上記にあります。入力ミスを申し訳ありません。 –
関数ポインタのアプローチは優れています.1つは、バインディングメソッドをオブジェクトに近似させることです。私はあなたの例が好きで、それを票決しました。 –
あなたはすべての答えを閲覧から見ることができるように、ライブラリがあり、 関数ポインタ、継承、カプセル化などの手段があります。すべて が利用可能です(C++はもともとCのフロントエンドでした)。
しかし、ソフトウェアにとって非常に重要な側面は、可読性が であることがわかりました。 10年前からコードを読もうとしましたか? その結果、私はC.
で オブジェクトのようなものをやったときに、最も単純なアプローチを取る傾向にある次のことを確認する:
- は期限を顧客のために、このです(もしそうなら、OOPを考えます) ?
- OOPを使用することはできますか(コードが少なくて済み、開発が速く、読みやすくなります)?
- ライブラリ(既存のコード、既存のテンプレート)を使用できますか?
- 私はメモリまたはCPU(たとえばArduino)に制約されていますか?
- Cを使用する別の技術的な理由はありますか?
- 私のCを非常にシンプルで読みやすく保つことができますか?
- 私のプロジェクトにはどんなOOP機能が本当に必要ですか?
私は通常、 に私のコードをカプセル化し、非常に読みやすいインターフェイスを提供することができますGLIB APIのようなものに戻ります。 がさらに必要な場合は、多型のための関数ポインタを追加します。
- 1. JSONまたはXMLを決定するためにどのような戦略を使用しますか?
- 2. npmパッケージを利用するための構築戦略
- 3. ProGuardでは、テスト戦略にどのような影響がありますか?
- 4. (C++)CURL_STATICLIB:そのようなファイルやディレクトリはありません
- 5. C++ variantこのようなファイルやディレクトリはありません
- 6. `` Concat '戦略を使用するために `Source.combine`を明示的にマークする方法はありますか?
- 7. 人々はAngularJsのページ間をリンクするためにどのような概念を使用しますか?
- 8. codeigniterを使用したスケーラブルなマルチサイト戦略はありますか?
- 9. WindowsでPerl Unicode :: Mapを構築するにはどのようにMS C++ Express 2008を使用しますか?
- 10. トレーニングデータベースを構築するための戦略/ツール
- 11. Webアプリケーションのパフォーマンスを向上させるためにどのような戦略を採用しましたか?
- 12. C#データアクセス層(EFが、SPやオブジェクトではありません)
- 13. C++のメンバーインスタンスはどのように構築されますか?
- 14. PHPを使用したサブドメインの戦略のための戦略
- 15. C#で使用するUDPを介したC++クラスですが、どのようなオプションがありますか?
- 16. なぜGuidはC#のオブジェクトではありませんか?
- 17. cやC++に、グラフや木などのデータ構造を実装するヘッダファイルはありますか?
- 18. Android Dev Teamの人々は、図や図を作成するためにどのツールを使用しますか?
- 19. SSOプロキシを構築するためのライブラリやフレームワークはありますか?
- 20. C#でOutOfMemoryExceptionを構築するメモリがないとどうなりますか?
- 21. 配列の省略形:{}や[]のようなリテラル構文はありますか?
- 22. C#クライアントを使用してC++チャットサーバーを作成するための記事やアドバイスはありますか?
- 23. モバイルアプリケーションを構築するための良い戦略が必要です
- 24. C++インタプリタ(コンパイラではありません)を使用しましたか?
- 25. CGPathを構築するためのツールはありますか? (XCode/Swiftなど)
- 26. エラー:Objective-Cモジュール 'Foundation'を構築できませんでした
- 27. Objective cモジュールを構築できませんでした。
- 28. 人気のあるGitレイアウト戦略は何ですか?
- 29. SWIGを使用してCでPerlハッシュを構築するにはどうすればよいですか?
- 30. gdbはC++のスタックトレースをどのように再構築しますか?
私はいつも「オブジェクトベース」のCプログラミングスタイルを使用していましたが、これはC++の多くの方がずっと簡単です。なぜあなたはそれを使いたくないと思うのですか? –
@ Neeil:理由がない場合、GObjectはありません。 Cのための多くの理由があります:旧式のプラットフォーム、protability、バイナリABI互換性、あなたは名前を付けます。 – EFraim
@EFraim私はこれらの理由を十分に認識していますが、私は質問者の理由を聞いていました。 –