何时应在非成员函数之前编写关键字 'static'?
When should I write the keyword 'static' before a non-member function?
我最近在一个函数之前看到了一些关于static
关键字的SO,我想知道如何正确使用它。
1)什么时候应该在非成员函数之前写关键字static
?
2)在头文件中定义静态非成员函数是否危险?为什么(不)?
(一边提问)
3)是否有可能在头文件中以某种方式定义一个类,以便它只在您首先使用它的翻译单元中可用?
(我问这个的原因是因为我正在学习STL,它可能是我的谓词等(可能是函子)的一个很好的解决方案,因为我不喜欢在cpp文件中定义成员函数以外的函数)
(另外,我认为它在某种程度上与原始问题有关,因为根据我目前的推理,它会在函数之前做与static
相同的事情)
编辑
在看到一些答案时出现的另一个问题:
4)许多人告诉我必须在头文件中声明静态函数,并在源文件中定义它。但是静态函数是翻译单元所特有的。链接器如何知道哪个翻译单元是唯一的,因为头文件不直接与源文件相关(只有当您包含它们时)?
static
,我认为你正在使用它,是一种符号隐藏的手段。声明static
的函数没有全局可见性(类unix的nm
将显示为't'而不是't')。这些函数不能从其他翻译单元调用。
对于c++,这种意义上的static
或多或少已经被匿名命名空间所取代,例如
static int x = 0;
与
相当namespace {
int x = 0;
}
请注意,每个编译单元的匿名命名空间是唯一的。
与static
不同的是,匿名命名空间也适用于类。你可以这样写
namespace {
class Foo{};
}
并在其他翻译单元中为不相关的类重用该类名。我想这正是你要说的。
编译器实际上给你这样定义的每个符号一个唯一的名字(我认为它包括编译时间)。这些符号永远不会被其他翻译单元使用,也不会与其他翻译单元的符号发生冲突。
注意所有声明为inline
的非成员函数在默认情况下也是static
。这是static
最常见的(隐式的)用法。至于第2点,在头文件中定义static
而不是inline
函数是一种非常极端的情况:它本身并不危险,但很少有用,可能会令人困惑。这样的函数可能会在每个翻译单元中发出,也可能不会。如果您从未在某些tu中实际调用该函数,编译器可能会生成警告。如果静态函数中有一个静态变量,那么即使在单个.h
中有一个定义,每个翻译单元也会有一个单独的变量,这可能会令人困惑。只是没有很多(非内联)用例。
关于第4点,我怀疑这些人将static
的静态成员函数含义与static
的链接含义混淆了。这是为后者使用匿名名称空间的一个很好的理由。
关键字"static"被重载以表示几种不同的含义:
-
它可以控制可见性(C和c++)
-
它可以在子例程调用之间保持变量(C和c++)
…和…
-
它可以使方法或成员应用于整个类(而不仅仅是类实例:仅限c++)
简短的回答:最好不要使用任何语言工具,除非
a)你很确定你需要它
b)你非常确定你知道你在做什么(即你知道你为什么需要它)
在.cpp文件中声明静态变量或独立函数绝对没有错。在头文件中声明静态变量或独立函数可能是不明智的。而且,如果您确实需要类函数或类成员的"静态",那么头文件无疑是定义它的最佳位置。
这里有一个很好的链接:
http://www.cprogramming.com/tutorial/statickeyword.html如果非成员函数只能在声明它们的代码文件中可见,则应该将其定义为静态函数。
同样的问题在cplusplus.com
- 这些示例中的 "static" 关键字是否有所作为?
- 为什么静态成员函数定义不能有关键字"static"?
- C++不使用"inline"或"static"无类函数的关键字时出现重定义链接错误
- 使用 static 关键字禁止使用堆栈内存
- 二元运算符声明的'static'关键字
- static关键字是否影响作用域
- 关键字 static 在 C 和 C++ 之间有什么区别?
- static关键字在类内部和类外部
- 为什么 C++ 不接受函数定义中的 static 关键字
- c++static关键字对大括号有什么作用
- static 关键字是否在 C/C++ 和存储级别中起作用?
- const/static关键字是否在变量声明中传播
- 不能对 c++ 类实现文件中的静态方法使用 "static" 关键字 (.cpp)
- 何时应在非成员函数之前编写关键字 'static'?
- 如何在c++中使用class中的static关键字来模拟Python中@classmethod的行为
- 为什么不允许将类成员定义的' static '关键字放在命名空间范围内?
- 为什么在这个模板代码中需要static关键字?
- 如果我们在c++中使用static关键字删除[-Wreturn local-addr](警告:返回本地变量的地址),可以
- 我可以使用static关键字只分配一次新内存吗
- "static"关键字与类的变量、函数和对象等有什么用?