C++文件作用域静态函数

3

何时应考虑使用定义在文件作用域的静态函数?

通常我会在需要一个任务不属于任何类的成员函数,且该任务只在某个源文件中需要(重复)执行时使用它们。

我的使用方式符合此特性存在的原因吗?还是我正在劫持一个本来用于其他用途的概念?

3个回答

5

这是文件作用域静态函数的一个完全有效的用法,但请记住,这种使用静态的方法已经被弃用了相当长一段时间。通常更喜欢使用匿名命名空间。


2
首先,你要找的术语是“内部链接”。你的问题应该是:“哪些实体应该具有内部链接?”关键字static或者无名命名空间只是实现内部链接的机制。
现在答案显而易见:所有仅在一个单独的翻译单元中使用的实体都可以具有内部链接,并且这样做有好处:一方面,编译器可以利用实体永远不会被任何其他翻译单元看到的信息,因此它可以避免发出可能需要的代码,或更加积极地进行内联。另一个原因是,如果你恰好选择了一个在其他TU中也被本地使用的名称,你可以最小化意外ODR违规的风险。
一个典型的例子如下: my_lib.hpp:
#ifndef H_MY_LIB
#define H_MY_LIB

namespace foo
{
    void do_an_awesome_thing(void * p, std::size_t n);
}

#endif

my_lib.cpp:

#include "my_lib.hpp"

namespace foo
{
    namespace
    {
        void helper(void * p) { /* ... */ }
        bool aux(std::size_t n, float f) { /* ... */ }

        constexpr char usage[] = R"(This is how you do it...)";
        constexpr float some_factor = 1.25;
    }

    void do_an_awesome_thing(void *p, std::size_t n)
    {
        if (!aux(n, some_factor)) { LOG_AND_DIE(usage); }
        helper(p);
    }
}

现在您可以确信,您的翻译单元不会对程序的其余部分产生任何不必要的链接时间负担。
未命名命名空间的放置是一种品味问题;您可以将其放在常规命名空间内或顶层。效果相同。

2

当需要函数和/或数据不是类接口的一部分,而是实现细节时,我会做类似的事情。

但我不使用关键字static。相反,我将函数和/或数据放在一个未命名的命名空间中。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接