静态自由函数或助手的成员函数

static free functions or member functions for helpers?

本文关键字:函数 成员 自由 静态      更新时间:2023-10-16

假设您有以下非静态成员函数:

// .h
struct C {
    void f();
}

现在假设您想通过使用C::f特有的一些子函数来实现C::f,以使其更短、更可读;例如:

// .cpp
void C::f() {
    h1();
    h2();
    //...
    hn();
}

假设这些h()的许多函数不需要访问任何数据成员。这意味着您可以将函数定义为静态自由函数(在一个.cpp中)或成员函数(静态或非静态)。

你会让它们成为静态的自由函数还是C的函数成员?

第一种情况的一个优点是,您不必在C:中声明它们

// .cpp
static void h1() {//...}
static void h2() {//...}
static void hn() {//...}

此外,如果我没有错的话,就没有全局命名空间污染的风险,因为它们是静态,也就是说,它们只能从同一单元.cpp内的其他函数中看到(其中还定义了C::f)。

而在第二种情况下,您必须在C中声明它们,尽管正如我所说,它们应该只由C::f使用。

// .h
struct C {
    void f();
  private:
    static void h1(); // can be either static or non-static
    static void h2();
    static void hn();
}
// .cpp
void C::h1() {//...}
void C::h2() {//...}
void C::hn() {//...}

我认为第二个版本会导致代码膨胀,这是没有充分理由的,尤其是如果您最终不得不拆分其他长成员函数,如C::f,以使代码更可读。

我建议使用匿名名称空间:

namespace {
    void C::h1() {/...}
    void C::h2() {/...}
    void C::h3() {/...}
}

(见此问题)

通过这种方式,您可以保证函数在定义的文件外不可见,因此您不会污染全局命名空间-这将是我对免费静态函数的主要关注。

使它们成为类的私有成员会将函数接口暴露给整个世界(当您发布*.h文件时),从而使接口变得更加复杂。(这里可以添加更多的参数,例如,在更改私有函数的定义时,编译时间会更长)

搜索"匿名名称空间"会引发一些关于这个主题的有趣讨论。

只有您才能回答这个问题。如果它们永远不会在C::f之外使用,那么污染全局命名空间就没有意义了。我个人会让他们成为C的成员。如果它们可以被标记为静态,那么就这样做,但如果它们真的只对f重要,那么就给它们命名一些表明这一点的东西,不要担心static