我最近在函数前看到了关于static
关键字的问题,我想知道如何正确使用它。
1)我应该何时在非成员函数之前编写关键字static
?
2)在标题中定义静态非成员函数是否危险?为什么(不是)?
(旁边问题)
3)是否可以以某种方式在头文件中定义一个类,以便它只能在您首先使用它的翻译单元中使用?
(我问这个的原因是因为我正在学习STL,它可能是我的谓词等(可能是函子)的一个很好的解决方案,因为我不喜欢定义除成员之外的函数-cpp文件中的函数)
(另外,我认为它与原始问题有关,因为根据我目前的推理,它会在函数执行之前与static
做同样的事情) < / p>
在看到一些答案时出现的另一个问题是:
4)很多人告诉我,我必须在标头中声明静态函数,并在源文件中定义它。但静态功能对于翻译单元是唯一的。链接器如何知道 哪个 转换单元是唯一的,因为头文件不直接与源文件相关(仅当您包含它们时)?
答案 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)
当非成员函数仅在声明它们的代码文件中可见时,您应该将非成员函数定义为静态函数。
上提出了同样的问题