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


78

使用C ++从以下代码中获取错误。

Main.cpp

#include "file.h"

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

文件.h

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 ++中组织代码文件”,但不了解此代码有什么问题。


2
您如何链接?“ gcc -o Test Main.cpp File.cpp -lstdc ++”还是XCode / VisualStudio / Eclipse中的某个位置?
维克多·拉蒂波夫

2
@ViktorLatypov说了什么。告诉我们您如何编译它。
布雷迪

@ViktorLatypov:我在C ++ / CLI项目中的Visual Studio 2013中选择文件,然后单击“编译”按钮来遇到此问题。(C ++按钮的编译按钮未链接,并且不应遇到此错误,但是C ++ / CLI可能不同吗?)(哦,等等,刚刚看到了最佳答案。我已将static类转换为名称空间>。<忘了。)
Mooing Duck 2014年

Answers:


129

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

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

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


23

更改

static int GetInteger();

int GetInteger();

static在这种情况下,将为方法提供内部linkeage,这意味着您只能在定义它的翻译单元中使用它。

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


6

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


3

声明为static的函数在包含文件本地。因此,您必须在与调用该函数的文件相同的文件中定义该函数。如果要使其可从其他文件调用,则不得将其声明为静态。


2

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

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


2

如果所有内容都在同一个翻译单元中,则应该可以使用。您可能没有将File.cpp编译为与Main.cpp相同的单元。

g++ -Wall File.cpp Main.cpp

如果每个文件分别编译,则必须使该函数extern在不同的翻译单元中使用。

extern int GetInteger();

这与

int GetInteger();

他使用的是Visual Studio,而不是g ++
Brady 2012年

0

考虑使用名称空间...

适用于不需要内部成员变量的代码的逻辑部分。意思是,您的GetInteger()函数不需要引用内部常量。为了使函数在代码中井井有条,请考虑使用名称空间。这样可以避免函数名冲突(这可以避免您因可能的LNK错误而头痛的时间)。该代码仍然可以按照您设置的方式工作,并且仍在可接受的答案范围内工作。此外,您的名称空间名称可以帮助您快速调试。

Main.cpp

#include "file.h"

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

文件.h

namespace HELPERS
{
    int GetInteger();
}

File.cpp

#include "file.h"

int HELPERS::GetInteger()
{
   return 1;
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.