在 C++ 中声明但未定义的静态函数
Posted
技术标签:
【中文标题】在 C++ 中声明但未定义的静态函数【英文标题】:Static function declared but not defined in C++ 【发布时间】:2012-06-04 11:32:10 【问题描述】:我在使用 C++ 的以下代码中遇到错误。
Main.cpp
#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++",但不明白这段代码有什么问题。
【问题讨论】:
你如何链接它? "gcc -o Test Main.cpp File.cpp -lstdc++" 或 XCode/VisualStudio/Eclipse 中的某处? @ViktorLatypov 说了什么。向我们展示你是如何编译它的。 @ViktorLatypov:我在 C++/CLI 项目中选择 Visual Studio 2013 中的文件并单击编译按钮时遇到了这个问题。 (C++ 按钮的编译按钮没有链接,也不应该遇到此错误,但也许 C++/CLI 不同?)(哦等等,刚刚看到最佳答案。我已将static
类转换为命名空间>.
【参考方案1】:
改变
static int GetInteger();
到
int GetInteger();
static
在这种情况下给出了方法internal linkeage,这意味着您只能在定义它的翻译单元中使用它。
您在File.cpp
中定义它并尝试在main.cpp
中使用它,但main 没有它的定义,因为您声明了它static
。
【讨论】:
【参考方案2】:在 C++ 中,static
在全局/命名空间范围内意味着函数/变量仅在定义它的翻译单元中使用,而不在其他翻译单元中使用。
在这里,您尝试使用来自不同翻译单元 (Main.cpp
) 的静态函数,而不是定义它的翻译单元 (File.cpp
)。
删除static
,它应该可以正常工作。
【讨论】:
【参考方案3】:声明为静态的函数是包含文件的本地函数。因此,您必须在与调用它的文件相同的文件中定义该函数。如果你想让它可以从其他文件中调用,你不能将它声明为静态的。
【讨论】:
【参考方案4】:如果所有内容都在同一个翻译单元中,它应该可以工作。 您可能没有将 File.cpp 编译到与 Main.cpp 相同的单元中。
g++ -Wall File.cpp Main.cpp
如果每个文件都单独编译,则必须将函数设为 extern
才能从
不同的翻译单元。
extern int GetInteger();
与
相同int GetInteger();
【讨论】:
他使用的是 Visual Studio,而不是 g++【参考方案5】:因为在这种情况下,static
表示函数的名称有
内部联动;一个翻译单元中的GetInteger
不相关
到任何其他翻译单元中的GetInteger
。关键字static
是
重载:在某些情况下,它会影响生命周期,而在其他情况下,会影响绑定。
这里特别令人困惑,因为“静态”也是一个名称
寿命。在命名空间范围内声明的函数和数据,总是
有静态生命周期;当static
出现在他们的声明中时,它
导致内部绑定,而不是外部绑定。
【讨论】:
【参考方案6】:据我了解,静态函数的名称与定义它们的文件名混淆,因此当您在 main.cpp 中包含 file.h 时,尽管您在文件中定义了 GetInteger(),但 GetInteger() 会与 main.cpp 混淆.cpp 但由于它是静态的,因此它也会被破坏,并且链接器无法找到 GetInteger() 的定义,因为不存在此名称的函数。
我相信吸取的教训是不要在头文件中声明静态函数,因为它们不打算成为接口的一部分。
【讨论】:
【参考方案7】:考虑使用命名空间...
用于不需要内部成员变量的代码逻辑部分。这意味着,您的 GetInteger()
函数不需要引用内部常量变量。为了使您的函数在代码中井井有条,请考虑使用命名空间。这可以防止函数名称发生冲突(这将节省您因可能出现的LNK
错误而头疼的时间)。该代码仍然按照您设置的方式工作,并且仍然在接受的答案范围内工作。此外,您的命名空间名称可以帮助您快速调试。
Main.cpp
#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;
【讨论】:
以上是关于在 C++ 中声明但未定义的静态函数的主要内容,如果未能解决你的问题,请参考以下文章