C++を使用して次のコードからエラーが発生します。
Main.cpp
#include "file.h"
int main()
{
int k = GetInteger();
return 0;
}
File.h
static int GetInteger();
File.cpp
#include "file.h"
static int GetInteger()
{
return 1;
}
私が得るエラー:
Error C2129: static function 'int GetInteger(void)' declared but not defined.
有名な記事 "CおよびC++でのコードファイルの整理" を読みましたが、このコードの何が問題なのか理解できません。
C++では、グローバル/ネームスペーススコープのstatic
は、関数/変数が定義されている翻訳単位でのみ使用され、他の翻訳単位では使用されないことを意味します。
ここでは、別の翻訳単位の静的関数(Main.cpp
)定義されているもの(File.cpp
)。
static
を削除すると、正常に機能するはずです。
変化する
static int GetInteger();
に
int GetInteger();
この場合のstatic
は、メソッドinternal linkeageを提供します。つまり、それを定義した翻訳単位でのみ使用できます。
File.cpp
で定義し、main.cpp
で使用しようとしますが、static
を宣言したため、mainには定義がありません。
この場合、static
は関数の名前に内部リンケージがあることを意味するためです。 1つの翻訳単位のGetInteger
は、他の翻訳単位のGetInteger
とは無関係です。キーワードstatic
はオーバーロードされています。場合によっては、存続期間に影響し、他の場合にはバインディングに影響します。 「静的」は生涯の名前でもあるため、ここでは特に混乱を招きます。関数、および名前空間スコープで宣言されたデータには、常に静的な有効期間があります。 static
が宣言にある場合、外部ではなく内部バインディングが発生します。
静的として宣言された関数は、包含ファイルに対してローカルです。そのため、関数を呼び出すファイルと同じファイルで関数を定義する必要があります。他のファイルから呼び出し可能にする場合は、静的として宣言しないでください。
すべてが同じ翻訳単位にある場合は、動作するはずです。 File.cppをMain.cppと同じユニットにコンパイルしていない可能性があります。
g++ -Wall File.cpp Main.cpp
各ファイルを個別にコンパイルする場合、異なる翻訳単位から使用されるように、関数をextern
にする必要があります。
extern int GetInteger();
と同じです
int GetInteger();
私の理解から、静的関数は定義されているファイル名でマングルされているため、file.hをmain.cppに含めると、GetInteger()はfile.cppでGetInteger()を定義していますが、main.cppでマングルされますが、それは静的であるため、マングルされ、この名前の関数が存在しないため、リンカはGetInteger()の定義を見つけることができません。
学んだ教訓は、インターフェイスの一部となることを意図していないため、ヘッダーファイルで静的関数を宣言しないことだと思います。