5

より大きなプロジェクトに取り組むことに関しては、私はいくつかの独自のタイプ(例えばmyType)を投入したいと思います。「急いで」アプローチは、それらのtypedefをヘッダー(たとえばmyType.h)に入れ、それらの型で動作する一連の関数と一緒にすることです。

新しいタイプをどこかで使用する場合はmyType.h、ソースファイルに含めます。罰金。

しかし、関数シグニチャの引数として新しい型をどこかで使用したい場合は、関数myType.hを含むモジュールのヘッダーにを含める必要があります。いずれかのtypedefを使用すると、これは問題ないように見えますが、タイプが多いほど、必要なヘッダーに含まれるものが多くなり、他の独自のタイプを含むtypeを使用しながら、さらにヘッダーを含めることができます。これは私が「依存関係地獄」と呼ぶものをもたらしています。

このジレンマを解決するための賢く、スタイリッシュで、ベストプラクティスの方法はありますか?

これらの型をvoidポインターとして渡し、関数内にキャストして戻す可能性があることは認識していますが、コンパイラーからの重要な型チェックを失います。

総統は、externこのあたりで最悪の慣行と見なされています。

編集:

詳細に:

myType.h

#include "otherType.h"

typedef struct {
  char Name[32];
  int Size;
  otherType someType;
} myType;

processSomeHow(myType _myType, int NewSize);

otherType.h

#define SOME_CONST 32

typedef struct { [...] } otherType;

someModule.h

#include "myType.h"

int specialProcessSomeHow(myType _myType);

someModule.c

int specialProcessSomeHow(myType _myType)
{
  int Size = 64;
  return(processSomeHow(_myType, Size));
}

今、私はotherType.h間接的にsomeModule.h、さらに悪いことに、を含むすべてのモジュールにそれを含めますsomeModule.h。今、私はSOME_CONSTどこにでもいるので、どこから来たのかを理解するのは難しいです。インクルードツリーを2つ維持する必要があります。

4

3 に答える 3

1

gtkライブラリのように、1つのヘッドファイルを使用して、必要に応じて分割することができます。

type.h
- myType.h
-- someType.h
- otherType.h
- List item

そしてあなたのCONST-問題:あなたがただ1つのc.fileのためにそれを必要とするならば。それらをHeaderFileで使用しないでください。また、「MY_TYPE_SOME_CONST」や「OTHER_TYPE_SOME_CONST」のように名前を付けることもできます。

//編集:

明確にするには、「this.h」ファイルを追加して名前を付けるだけです。

#ifndef TYPE_H_
#define TYPE_H_

#include myType.h
#include someType.h
#include otherType.h

#endif /* TYPE_H_ */

これで、タイプが必要なファイルごとに「#includethis.h」を使用できます。(this.hは本物ではありません、何かユニークな名前を付けてください)

于 2013-03-25T10:54:58.723 に答える
0

カスタム型には前方宣言を使用できます(おそらく使用する必要があります)。詳細はこちらをご覧ください:Cでの前方宣言を使用したtypedef stuct

インターフェイス(ヘッダー)には不完全な型(つまり、カスタム型へのポインター)が必要であり、ソースコード(cファイル)内にを含める必要がありますMy_Type.h

于 2013-03-25T09:30:32.277 に答える
0

あなたは不必要に心配しています:あなたがコンパイラにそれが仕事をするのに必要なすべての情報を与えているという理由だけで、「依存関係地獄」はありません。

これに関する私のルールは次のとおりです。

  • 常に、常にヘッダーガードを使用してください。
  • すべての.hファイルは、コンパイルするために必要な他のすべての.hファイルを明示的に#includeする必要があり、それ以上は含めないでください

したがって、bhがahの型を使用する場合、bhは。でなければなりません#include "a.h"b.cからの関数を使用しているa.hが、b.gからの型を使用していない場合は、b.c#includeahを使用する必要があります

  • externIIRCの最新のコンパイラはこれを正しく推測するため、.hファイルの関数にキーワードを指定する必要はありません。
  • グローバル変数に使用externすることは、正当な理由で眉をひそめる可能性があります。

  • グローバル名前空間の乱雑さ。C ++名前空間はこれに対処しますが、Cでは、すべてのグローバルタイプ、関数、およびの命名規則を使用する必要があり#definesます。自分に合った規則を選択してください。チームがすべてのソースファイルにLETTER-DIGIT-DIGITプレフィックスを正常に使用しているのを見てきたので、foo.h(たとえば)B04_foo.hになる可能性があり、すべての関数/タイプが同じB04_プレフィックスを取得します。少し粗雑ですが、機能します。私が言うように、あなたのために働くものを選んでください。

于 2013-03-25T11:13:32.870 に答える