5

複数のヘッダー ファイルがあり、それぞれの関数を登録するには、配列に数値を追加する必要があります。

現在、各ヘッダー ファイルに一意の名前を持つ関数があり、プログラム ファイルでは、これらすべての関数を 1 つの結合関数で呼び出す必要があります。

int register1() { return 100; }; //in header1.h
int register2() { return 200; }; //in header2.h
int register3() { return 300; }; //in header3.h
int register4() { return 400; }; //in header4.h
int registered[] = {register1(),register2(),register3(),register4()}; //main.c

しかし、ヘッダー ファイルを追加または削除するときに 2 か所を変更する必要があるため、これは非常に不便です。ヘッダー ファイルのみを変更することをお勧めします。プリプロセッサの定義について考えていたので、各ヘッダーで次のようなものを使用できます。

#define Registered Registered,100 // header1.h
#define Registered Registered,200 // header2.h
int registered[] = {Registered}; // main.c

しかし、新しい定義は古いものを再定義するため、これはもちろんコンパイルされません。定義を追加する方法はありますか?または、2 つのファイルを変更せずに配列に数値を追加する他の方法はありますか?

これは C++ ではなく C です。それ以外の場合は、配列に書き込むだけのコンストラクターでクラス インスタンスを使用します。そのように考えてください:

struct __header1{ __header1() { 
   global_array[global_array_ptr++] = 100; 
} } __header1_inst;

そして、それを素敵なマクロに変換します:

    #define register(hdr, func) struct __header##hdr{ __header##hdr() { \
       global_array[global_array_ptr++] = func; \
    } } __header##hdr##_inst;

   register(1, 100) // header1.h
   register(2, 200) // header2.h
4

1 に答える 1

1

私見、これはハックであり、私はそれに対してアドバイスします。C でそれを行うことができたとしても、そのようなヘッダー ファイルが複数のモジュールに含まれている状況を考えてみてください。そのようなモジュールごとに、グローバル配列に同一のエントリがあります。次に、C++ で実行できますが、そこではグローバル オブジェクトの初期化の順序が定義されていないため、グローバル配列の内容に依存する別のグローバル オブジェクトの初期化は信頼できません。

さらに、これは単純なことを行うのに非常に複雑な方法であり、意味をかなりあいまいにしています。配列を埋めるコード自体が複雑であることは別として、依存関係が些細なものを超えると、インクルードの追跡が負担になります。したがって、そのグローバル配列を特定の場所に明示的に入力するだけです。

于 2013-05-27T05:45:01.150 に答える