在 C + + 中声明但未定义的静态函数

下面使用 C + + 编写的代码出现了一个错误。

Main.cpp

#include "file.h"


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

档案

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 + + 组织代码文件”文章,但是不明白这段代码出了什么问题。

76688 次浏览

改变

static int GetInteger();

int GetInteger();

在本例中,static给出了方法 内部联系内部联系,这意味着您只能在定义它的翻译单元中使用它。

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

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

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

去掉 static,应该就没问题了。

函数声明为包含文件的静态 arelocal。因此,必须在调用它的文件中定义函数。如果您想使其可从其他文件调用,则不能将其声明为 static。

如果所有的东西都在同一个翻译单元里,那么它应该可以工作。 您可能没有将 File.cpp 编译成与 Main.cpp 相同的单元。

g++ -Wall File.cpp Main.cpp

如果每个文件都是单独编译的,那么函数必须设置为 extern才能从 不同的翻译单位。

extern int GetInteger();

也就是说

int GetInteger();

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

根据我的理解,静态函数的名称与定义它们的文件名混淆,所以当你在 main.cpp 中包含 file.h 时,GetInteger ()会与 main.cpp 混淆,虽然你在 file.cpp 中定义了 GetInteger () ,但是由于它是静态的,它也会被混淆,链接器找不到 GetInteger ()的定义,因为没有这个名称的函数存在。

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

考虑使用名称空间..。

用于不需要内部成员变量的代码逻辑部分。这意味着,GetInteger()函数不需要引用内部常量变量。为了在代码中保持函数的组织性,可以考虑使用命名空间。这样可以避免函数名的冲突(这样可以节省可能出现 LNK错误的时间)。代码仍然按照您设置的方式工作,并且仍然在可接受答案的范围内工作。此外,命名空间名称可以帮助您快速调试。

Main.cpp

#include "file.h"


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

档案

namespace HELPERS
{
int GetInteger();
}

File.cpp

#include "file.h"


int HELPERS::GetInteger()
{
return 1;
}