80

我在使用 C++ 的以下代码中遇到错误。

主文件

#include "file.h"

int main()
{
   int k = GetInteger();
   return 0;
}

文件.h

static int GetInteger();

文件.cpp

#include "file.h"

static int GetInteger()
{
   return 1;
}

我得到的错误:

Error C2129: static function 'int GetInteger(void)' declared but not defined.

我读过著名的文章“Organizing Code File in C and C++”,但不明白这段代码有什么问题。

4

7 回答 7

140

在 C++ 中,static在全局/命名空间范围内意味着函数/变量仅在定义它的翻译单元中使用,而不在其他翻译单元中使用。

在这里,您尝试使用来自不同翻译单元 ( Main.cpp) 的静态函数,而不是定义它的翻译单元 ( File.cpp)。

删除static它应该可以正常工作。

于 2012-05-30T08:41:40.620 回答
26

改变

static int GetInteger();

int GetInteger();

static在这种情况下,给出了方法internal linkeage,这意味着您只能在定义它的翻译单元中使用它。

您在 in 中定义它File.cpp并尝试在 in 中使用它main.cpp,但 main 没有它的定义,因为您声明了它static

于 2012-05-30T08:41:12.533 回答
8

因为在这种情况下,static意味着函数的名称具有内部链接;在一个翻译单元中与在任何其他翻译单元GetInteger中无关。GetInteger关键字static被重载:在某些情况下,它会影响生命周期,而在其他情况下,会影响绑定。这里特别令人困惑,因为“静态”也是一生的名字。在命名空间范围内声明的函数和数据始终具有静态生命周期;当static出现在他们的声明中时,它会导致内部绑定,而不是外部绑定。

于 2012-05-30T08:45:45.397 回答
4

声明为静态的函数是包含文件的本地函数。因此,您必须在与调用它的人相同的文件中定义该函数。如果你想让它可以从其他文件调用,你不能将它声明为静态的。

于 2012-05-30T08:42:25.857 回答
3

如果一切都在同一个翻译单元中,它应该可以工作。您可能没有将 File.cpp 编译到与 Main.cpp 相同的单元中。

g++ -Wall File.cpp Main.cpp

如果每个文件都是单独编译的,则必须使该函数extern从不同的翻译单元中使用。

extern int GetInteger();

这与

int GetInteger();
于 2012-05-30T08:45:33.593 回答
3

据我了解,静态函数的名称与定义它们的文件名相混淆,因此当您在 main.cpp 中包含 file.h 时,尽管您在 file.cpp 中定义了 GetInteger() 但 GetInteger() 会与 main.cpp 混淆因为它是静态的,所以它也会被破坏,并且链接器找不到 GetInteger() 的定义,因为不存在同名的函数。

我相信吸取的教训是不要在头文件中声明静态函数,因为它们不打算成为接口的一部分。

于 2012-05-30T08:47:58.500 回答
0

考虑使用命名空间...

对于不需要内部成员变量的代码的逻辑部分。这意味着,您的GetInteger()函数不需要引用内部常量变量。为了使您的函数在代码中井井有条,请考虑使用命名空间。这样可以防止函数名称发生冲突(这将节省您因可能出现的LNK错误而头疼的时间)。该代码仍然以您设置的方式工作,并且仍然在接受的答案范围内工作。此外,您的命名空间名称可以帮助您快速调试。

主文件

#include "file.h"

int main()
{
   int k = HELPERS::GetInteger();
   return 0;
}

文件.h

namespace HELPERS
{
    int GetInteger();
}

文件.cpp

#include "file.h"

int HELPERS::GetInteger()
{
   return 1;
}
于 2020-01-13T01:04:17.463 回答