在 C++ 中声明但未定义的静态函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10812769/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Static function declared but not defined in C++
提问by Sait
I'm getting an error from the following code using C++.
我从以下使用 C++ 的代码中收到错误消息。
Main.cpp
主程序
#include "file.h"
int main()
{
int k = GetInteger();
return 0;
}
File.h
文件.h
static int GetInteger();
File.cpp
文件.cpp
#include "file.h"
static int GetInteger()
{
return 1;
}
The error I get:
我得到的错误:
Error C2129: static function 'int GetInteger(void)' declared but not defined.
I've read the famous article "Organizing Code File in C and C++", but don't understand what is wrong with this code.
我读过著名的文章“Organizing Code File in C and C++”,但不明白这段代码有什么问题。
回答by HighCommander4
In C++, static
at global/namespace scope means the function/variable is only used in the translation unit where it is defined, not in other translation units.
在 C++ 中,static
在全局/命名空间范围内意味着函数/变量仅在定义它的翻译单元中使用,而不在其他翻译单元中使用。
Here you are trying to use a static function from a different translation unit (Main.cpp
) than the one in which it is defined (File.cpp
).
在这里,您尝试使用来自不同翻译单元 ( Main.cpp
)的静态函数,而不是定义它的翻译单元( File.cpp
)。
Remove the static
and it should work fine.
删除它static
,它应该可以正常工作。
回答by Luchian Grigore
Change
改变
static int GetInteger();
to
到
int GetInteger();
static
in this case gives the method internal linkeage, meaning that you can only use it in the translation unit where you define it.
static
在这种情况下,给出了方法internal linkeage,这意味着您只能在定义它的翻译单元中使用它。
You define it in File.cpp
and try to use it in main.cpp
, but main doesn't have a definition for it, since you declared it static
.
您定义它File.cpp
并尝试在 中使用它main.cpp
,但 main 没有定义它,因为您声明了它static
。
回答by James Kanze
Because in this case, static
means that the name of the function has
internal linkage; that GetInteger
in one translation unit is unrelated
to GetInteger
in any other translation unit. The keyword static
is
overloaded: in some cases, it affects lifetime, and in others, binding.
It's particularly confusing here, because "static" is also the name of a
lifetime. Functions, and data declared at namespace scope, always
have static lifetime; when static
appears in their declaration, it
causes internal binding, instead of external.
因为在这种情况下,static
意味着函数名具有内部链接;即GetInteger
在一个翻译单元是无关的GetInteger
任何其它翻译单元。关键字static
被重载:在某些情况下,它会影响生命周期,而在其他情况下,它会影响绑定。这里特别令人困惑,因为“静态”也是一生的名字。在命名空间范围内声明的函数和数据始终具有静态生命周期;当static
出现在他们的声明中时,它会导致内部绑定,而不是外部绑定。
回答by LeleDumbo
functions declared as static arelocal to the containing file. Therefore, you have to define the function in the same file as the ones who call it. If you want to make it callable from other file, you must NOT declare it as static.
声明为静态的函数是包含文件的本地函数。因此,您必须在与调用它的人相同的文件中定义该函数。如果要使其可从其他文件调用,则不得将其声明为静态。
回答by log0
If everything is in the same translation unit it should work. You probably did not compile File.cpp into the same unit as Main.cpp.
如果一切都在同一个翻译单元中,它应该可以工作。您可能没有将 File.cpp 编译为与 Main.cpp 相同的单元。
g++ -Wall File.cpp Main.cpp
If each file is compiled separately the function must be made extern
to be used from a
different translation unit.
如果每个文件是单独编译的,则必须使该函数extern
在不同的翻译单元中使用。
extern int GetInteger();
which is the same as
这与
int GetInteger();
回答by HBY4PI
From my understanding, static functions are name mangled with the filename in which they are defined so when you include file.h in main.cpp, GetInteger() get mangled with main.cpp though you have defined GetInteger() in file.cpp but since it is static it gets mangled too and linker cannot find the definition of GetInteger() as no function by this name exists.
根据我的理解,静态函数的名称与定义它们的文件名混淆,因此当您在 main.cpp 中包含 file.h 时,虽然您在 file.cpp 中定义了 GetInteger(),但 GetInteger() 会与 main.cpp 混淆,但是因为它是静态的,它也会被破坏,链接器找不到 GetInteger() 的定义,因为不存在这个名称的函数。
I believe lesson learnt is don't declare static functions in headerfile as are not intended to be a part of interface.
我相信吸取的教训是不要在头文件中声明静态函数,因为它们不打算成为接口的一部分。
回答by Andrew
Consider using namespaces...
考虑使用命名空间...
for logical sections of code that don't require internal member variables. Meaning, your GetInteger()
function doesn't require an internal constant variable to be referenced. In order to keep your functions organized in your code, consider using namespaces. This keeps function names from conflicting (which will save your hours of headache with possible LNK
errors). The code still works in the way you've set up and still works within the confines of the accepted answer. Additionally, your namespace name can help you quickly debug.
对于不需要内部成员变量的代码逻辑部分。意思是,您的GetInteger()
函数不需要引用内部常量变量。为了在代码中组织函数,请考虑使用命名空间。这可以防止函数名称发生冲突(这将节省您因可能LNK
出现的错误而头疼的时间)。该代码仍然以您设置的方式工作,并且仍然在接受的答案范围内工作。此外,您的命名空间名称可以帮助您快速调试。
Main.cpp
主程序
#include "file.h"
int main()
{
int k = HELPERS::GetInteger();
return 0;
}
File.h
文件.h
namespace HELPERS
{
int GetInteger();
}
File.cpp
文件.cpp
#include "file.h"
int HELPERS::GetInteger()
{
return 1;
}