将函数定义放入头文件中
如果要将函数定义放在头文件中,似乎有三种不同的解决方案:
- 将函数标记为
inline
- 将函数标记为
static
- 将函数放在匿名命名空间中
(直到最近,我什至都不知道#1。)那么这些解决方案有什么区别,什么时候我应该选择哪个?我处于只有标头的世界中,所以我确实需要标头文件中的定义。
If you want to put function definitions in header files, it appears there are three different solutions:
- mark the function as
inline
- mark the function as
static
- put the function in an anonymous namespace
(Until recently, I wasn't even aware of #1.) So what are the differences to these solutions, and when I should I prefer which? I'm in header-only world, so I really need the definitions in the header files.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
static
和未命名命名空间版本最终是相同的:每个翻译单元将包含它自己的函数版本,这意味着给定一个静态函数f
,指针&f
在每个翻译单元中都会不同,并且程序将包含 N 个不同版本的f
(二进制文件中有更多代码)。这不是在标头中提供一个函数的正确方法,它将提供N个不同(完全相同)的函数。如果函数包含
static
局部变量,那么将会有N个不同的static
局部变量...编辑:更明确的是:如果您想要在标头中提供函数的定义而不违反单一定义规则,则正确的方法是使函数
内联
。The
static
and unnamed namespace versions end up being the same: each Translation Unit will contain it's own version of the function, and that means that given a static functionf
, the pointer&f
will be different in each translation unit, and the program will contain N different versions off
(more code in the binary).This is not the right approach to provide a function in a header, it will provide N different (exactly equal) functions. If the function contains
static
locals then there will be N differentstatic
local variables...EDIT: To make this more explicit: if what you want is to provide the definition of a function in a header without breaking the One Definition Rule, the right approach is to make the function
inline
.据我所知,头文件中只能定义内联函数和模板函数。
static
函数已被弃用,应使用在未命名命名空间中定义的函数(请参阅 7.3.1.1 p2)。当您在标头中的未命名命名空间中定义函数时,包含该标头(直接或间接)的每个源代码都将具有唯一的定义(请参阅 7.3.1.1 p1)。因此,不应在头文件中的未命名命名空间中定义函数(仅在源文件中)。引用的标准来自 c++03 标准。
编辑:
下一个示例演示了为什么函数和变量不应定义到标头中的未命名命名空间中:
ops .hpp 包含:
dk1.hpp 包含:
dk1.cpp 包含:
dk.cpp 包含:
像这样编译:
并且输出 :
ops 变量
a
对于源文件dk1.cpp
和dk.cpp
是不同的As far as I know, only
inline
and template functions can be defined in header files.static
functions are deprecated, and functions defined in an unnamed namespace should be used instead (see 7.3.1.1 p2). When you define a function in an unnamed namespace in a header, then every source code including that header (directly or indirectly) will have an unique definition (see 7.3.1.1 p1). Therefore, functions should not be defined in the unnamed namespace in header files (only in source files).The standard referenced are from the c++03 standard.
EDIT:
Next example demonstrates why functions and variables shouldn't be defined into unnamed namespace in headers :
ops.hpp contains:
dk1.hpp contains:
dk1.cpp contains:
dk.cpp contains :
Compile like this:
and the output :
ops the variable
a
is different for the source filedk1.cpp
anddk.cpp
static
函数(相当于匿名命名空间)为每个 TU 接收不同的副本。如果函数是可重入的,则这基本上是相同的(某些编译器可能具有汇编级差异),但如果不是,则每个 TU 都会有不同的静态数据。内联函数是折叠的——也就是说,它们对于每个 TU 仅有一份静态数据副本。static
functions (equivalent to anonymous namespace) receive different copies for each TU. If the function is re-entrant this is basically identical (some compilers might have assembly-level differences) but if it isn't then it will have different static data for each TU. Inline functions are folded- that is, they have only one copy of static data for every TU.您可以考虑将方法包装在类中而不是命名空间中。将这些方法声明为静态方法并删除类的构造函数以强调这不是要实例化的对象。
您将获得与属于仅具有单个实现的命名空间相同的一般行为。
You could consider wrapping the methods in a class instead of a namespace. Declare these methods as static and delete the constructor of the class to reinforce that this is not an object to be instantiated.
You get the same general behavior as it belonging to a namespace with only a single implementation.