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

xcr*_*ypt 23 c++ linker static

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

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

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


(附带问题)

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

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

(另外,我认为它与原始问题有关,因为根据我目前的推理,它会像static函数之前那样做)

编辑

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

4)很多人告诉我,我必须在头文件中声明静态函数,并在源文件中定义它.但静态函数对于翻译单元是唯一的.链接器怎样才能知道哪些翻译单元是独一无二的,因为头文件不直接涉及到一个源文件(仅当您包括他们)?

smp*_*kes 20

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

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

static int x = 0;
Run Code Online (Sandbox Code Playgroud)

相当于

namespace {
  int x = 0;
}
Run Code Online (Sandbox Code Playgroud)

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

与此不同static,匿名命名空间也适用于类.你可以这么说

namespace {
 class Foo{};
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


pau*_*sm4 5

关键字“ static”已重载,表示几项不同的事情:

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

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

    ...和...

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

简短的答案:除非没有使用,否则最好不要使用任何语言工具

a)您确定需要它

b)您非常确定自己知道自己在做什么(即,您知道为什么需要它)

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

这是一个很好的链接:

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

希望有帮助