web-dev-qa-db-ja.com

C ++で宣言されているが定義されていない静的関数

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++でのコードファイルの整理" を読みましたが、このコードの何が問題なのか理解できません。

61
Sait

C++では、グローバル/ネームスペーススコープのstaticは、関数/変数が定義されている翻訳単位でのみ使用され、他の翻訳単位では使用されないことを意味します。

ここでは、別の翻訳単位の静的関数(Main.cpp)定義されているもの(File.cpp)。

staticを削除すると、正常に機能するはずです。

117
HighCommander4

変化する

static int GetInteger();

int GetInteger();

この場合のstaticは、メソッドinternal linkeageを提供します。つまり、それを定義した翻訳単位でのみ使用できます。

File.cppで定義し、main.cppで使用しようとしますが、staticを宣言したため、mainには定義がありません。

21
Luchian Grigore

この場合、staticは関数の名前に内部リンケージがあることを意味するためです。 1つの翻訳単位のGetIntegerは、他の翻訳単位のGetIntegerとは無関係です。キーワードstaticはオーバーロードされています。場合によっては、存続期間に影響し、他の場合にはバインディングに影響します。 「静的」は生涯の名前でもあるため、ここでは特に混乱を招きます。関数、および名前空間スコープで宣言されたデータには、常に静的な有効期間があります。 staticが宣言にある場合、外部ではなく内部バインディングが発生します。

6
James Kanze

静的として宣言された関数は、包含ファイルに対してローカルです。そのため、関数を呼び出すファイルと同じファイルで関数を定義する必要があります。他のファイルから呼び出し可能にする場合は、静的として宣言しないでください。

3
LeleDumbo

すべてが同じ翻訳単位にある場合は、動作するはずです。 File.cppをMain.cppと同じユニットにコンパイルしていない可能性があります。

g++ -Wall File.cpp Main.cpp

各ファイルを個別にコンパイルする場合、異なる翻訳単位から使用されるように、関数をexternにする必要があります。

extern int GetInteger();

と同じです

int GetInteger();
2
log0

私の理解から、静的関数は定義されているファイル名でマングルされているため、file.hをmain.cppに含めると、GetInteger()はfile.cppでGetInteger()を定義していますが、main.cppでマングルされますが、それは静的であるため、マングルされ、この名前の関数が存在しないため、リンカはGetInteger()の定義を見つけることができません。

学んだ教訓は、インターフェイスの一部となることを意図していないため、ヘッダーファイルで静的関数を宣言しないことだと思います。

2
HBY4PI