我什么时候应该在非成员函数之前写关键字'static'?

时间:2011-12-06 21:02:50

标签: c++ static linker

我最近在函数前看到了关于static关键字的问题,我想知道如何正确使用它。

1)我应该何时在非成员函数之前编写关键字static

2)在标题中定义静态非成员函数是否危险?为什么(不是)?


(旁边问题)

3)是否可以以某种方式在头文件中定义一个类,以便它只能在您首先使用它的翻译单元中使用?

(我问这个的原因是因为我正在学习STL,它可能是我的谓词等(可能是函子)的一个很好的解决方案,因为我不喜欢定义除成员之外的函数-cpp文件中的函数)

(另外,我认为它与原始问题有关,因为根据我目前的推理,它会在函数执行之前与static做同样的事情) < / p>

修改

在看到一些答案时出现的另一个问题是:

4)很多人告诉我,我必须在标头中声明静态函数,并在源文件中定义它。但静态功能对于翻译单元是唯一的。链接器如何知道 哪个 转换单元是唯一的,因为头文件不直接与源文件相关(仅当您包含它们时)?

3 个答案:

答案 0 :(得分:17)

static,我认为你正在使用它,是一种符号隐藏的方法。声明static的函数没有全局可见性(类似Unix的nm会将这些函数显示为't'而不是'T')。无法从其他翻译单元调用这些函数。

对于C ++,这个意义上的static或多或少被匿名命名空间替换,例如,

static int x = 0;

非常相当于

namespace {
  int x = 0;
}

请注意,匿名命名空间对于每个编译单元都是唯一的。

static不同,匿名命名空间也适用于类。你可以这样说

namespace {
 class Foo{};
}

并在其他翻译单元中为不相关的类重用该类名。我认为这是你的观点3.

编译器实际上为这个定义的每个符号赋予一个唯一的名称(我认为它包括编译时间)。这些符号永远不会被另一个翻译单元使用,并且永远不会与另一个翻译单元的符号发生碰撞。

请注意,声明为inline的所有非成员函数也默认为static。这是static最常见(和隐含)的用法。至于第2点,在标题中定义static而不是inline函数是一个相当不错的案例:它本身并不危险,但它很少有用,可能会令人困惑。在每个翻译单元中可能会或可能不会发出这样的功能。如果您从未在某些TU中实际调用该函数,则编译器可能会生成警告。如果静态函数在其中包含静态变量,则每个翻译单元都会获得一个单独的变量,即使在单个.h中有一个定义也可能会造成混淆。没有很多(非内联)用例。

至于第4点,我怀疑那些人正在将static的静态成员函数含义与static的连接含义混淆。对于后者使用匿名命名空间,这是一个很好的理由。

答案 1 :(得分:4)

关键字“static”被重载意味着几个不同的东西:

  • 它可以控制可见性(C和C ++)

  • 它可以在子程序调用(C和C ++)之间保存变量

    ......和......

  • 它可以使方法或成员适用于整个类(而不仅仅是一个类实例:仅限C ++)

简短回答:除非

,否则最好不要使用任何语言工具

a)你很确定你需要它

b)你很确定你知道自己在做什么(即你知道为什么需要它)

在.cpp文件中声明静态变量或独立函数绝对没有错。在标头中声明静态变量或独立函数可能是不明智的。而且,如果你真的需要一个类函数或类成员的“静态”,那么标题可以说是定义它的最佳位置。

这是一个很好的链接:

http://www.cprogramming.com/tutorial/statickeyword.html

'希望有所帮助

答案 2 :(得分:1)

当非成员函数仅在声明它们的代码文件中可见时,您应该将非成员函数定义为静态函数。

cplusplus.com

上提出了同样的问题