私の短い答えはノーです。
static 関数を .h ファイルで宣言してはならないことを指摘するコメント (非表示にする必要がある部分です。これは結局のところ static です) を無視して、次の点に注意してください。
モジュールの消費者から実装を分離するために、インターフェイスを使用しようとしているようです。高貴な目標。これにより、呼び出しコードを壊すことなく .c ファイルで実装を変更できるため、柔軟性が向上します。ただし、定義したインターフェースについて考えてみてください。
このモジュールを使用するすべてのコードは、Init を介して Interface インスタンスを取得できることが保証されている必要があります (ただし、これは .h ファイルに含める必要があります)。その Interface インスタンスは、使用する関数を指します。そのような関数の 1 つに署名があります。
int Fun(int);
それで、あなたは何を隠しましたか?もちろん、呼び出している関数を変更することはできますが、そのシグネチャを持つ関数を提供する必要があります。
または、.h を次のように定義することもできます。
int Fun(int);
そして、.c ファイルでは、次のようになります。
static int StaticFun(int i)
{
// something
}
int Fun(int i)
{
StaticFun(i);
}
Fun が管理する内部状態や構成ファイルに基づいて、Fun に別の関数を呼び出させることができます。なぜこれが良いのですか?単純であることに加えて、これは静的呼び出しです。たとえば、コンパイラは StaticFun への呼び出し、または関数 StaticFun を完全にインライン化できます。関数ポインターを介した呼び出しは、通常、顕著なパフォーマンス ヒットを引き起こします。
ここで、定義したような「インターフェイス」オブジェクトの場合があります。しかし、あなたの場合、変更なしではなく、そうではないことを示唆したいと思います。
Init
関数が次のように変更されたとします。
Interface* Init(some state info);
返される Interface オブジェクトは、渡された状態または構成に応じて変更できるようになりました。これにより、モジュールは関数を動的にマップできます。基本的に、私の意見では、実際にその下で静的関数を呼び出している場合、必要以上に多くの作業を行っており、コンパイラの最適化を妨げています。
注意として、インターフェース ルートに進む場合 (私は現在、似たようなプロジェクトに取り組んでいます)、変更を提案してもよろしいですか? 何かのようなもの...
.h ファイル:
const Interface* Init(some state);
.c ファイル:
static int FunTyp1(int);
static int FunTyp2(int);
static const Interface typ1 = { &FunTyp1 };
static const Interface typ2 = { &FunTyp2 };
const Interface* Init(some state)
{
if (some state == type1)
return &typ1;
else if (some state == type2)
return &typ2;
}
利点:
- インターフェイスを変更するためにコードを使用したくないと思いませんか? 少なくとも、私には正当な理由が思い浮かびません。
- これを静的に定義することで、不必要なヒープ割り当てと、消費者が Interface オブジェクトを繰り返し要求し、それらを解放するのを忘れたときのメモリ リークを回避できます (または、解放すべきかどうかわからない - このオブジェクトの所有者は誰ですか?)。
- 誰かがそれを変更することを心配することなく、プロセス内のすべての消費コードに対して Interface オブジェクトの単一 (静的) インスタンスを共有できます。
いくつかの静的に初期化されたインスタンスを持つことで、サポートする関数マッピングごとに異なる「インターフェイス」オブジェクトを定義できることに注意してください。