在 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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 14:29:27  来源:igfitidea点击:

Static function declared but not defined in C++

c++static-methods

提问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++, staticat 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 staticand it should work fine.

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

回答by Luchian Grigore

Change

改变

static int GetInteger();

to

int GetInteger();

staticin 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.cppand 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, staticmeans that the name of the function has internal linkage; that GetIntegerin one translation unit is unrelated to GetIntegerin any other translation unit. The keyword staticis 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 staticappears 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 externto 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 LNKerrors). 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;
}