1

正如在这个问题中回答的那样,我了解到static函数的关键字意味着它只能从该文件中的函数中看到。我认为未命名的命名空间可以用于相同的目的。

但是,通常,实现和头文件是分开的。因此,在我看来,程序员可以通过不在头文件中编写此类私有内容的声明来隐藏实现文件中的所有“私有内容”。

考虑到上述情况,未命名的static命名空间何时有用?我能想到的唯一情况是多个实现文件对应一个头文件。

4

1 回答 1

3

在实现文件中保留定义在任何意义上都不会使其成为私有。任何其他头文件或实现文件都可以声明该函数并使用它。这并不总是一件坏事——当我真正需要它时,我使用了库的部分私有实现(但我不建议这样做)。

拥有这种不那么私密的实现的更糟糕的部分是它可能违反单一定义规则。ODR 声明每个* 函数或变量在整个程序中必须有一个定义。如果有多个定义,则行为未定义**。
这意味着当您的文件中有您的不那么私密的实现并且没有人知道它时,他们可能会在不知不觉中编写具有相同名称和参数的函数并违反 ODR。

static对于应该限制在单个文件中的所有免费功能,使用或匿名命名空间是一个很好的做法。需要从其他文件中使用的函数不能使用此策略,因此为了限制违反 ODR 的风险,您应该使用描述性名称,也许还应该使用(命名的)命名空间。只要确保你没有过度使用命名空间


注意:在头文件中使用匿名命名空间没有意义。匿名命名空间将其内容的范围限制在它所在的翻译单元中,但头文件被复制并粘贴到(可能)多个 TU 中。匿名命名空间的一种用途是在仅标头库中,如本问题所述- 它允许在不违反 ODR 的情况下在头文件中创建全局对象(但代价是每个 TU 都有自己的该变量的副本)。


*除了模板函数、inline函数、类定义中定义的函数等等。即使这样,所有定义也必须完全相同。

**当我遇到一次时,链接器使用随机定义,无论它当时看到什么。欢闹和长时间的调试会议接踵而至。

于 2021-06-16T13:59:50.413 回答