只在.cpp中声明/定义静态方法可以吗



在许多情况下,我发现我的类需要私有函数来分解它们的功能并重用代码。典型的实施方式是:

MyClass.h

#include "AnotherClass.h"
class MyClass {
public:
    float foo() const;
private:
    float fooPrivate(const AnotherClass& ac) const; 
}

MyClass.cpp

#include "MyClass.h"
float MyClass::foo() const {
    return fooPrivate(AnotherClass());
}
float MyClass::fooPrivate(const AnotherClass& ac) const {
    return ac.foo();
}

这是可以的,但是在头文件中声明fooPrivate()在以下情况下可能会有问题:

  • 如果AnotherClass仅用于内部使用,并且在MyClass之外不需要,那么我们可能不希望在头文件中包含它。

  • 如果需要许多私有函数,我们就有可能用不必要的私有函数污染头文件,这会使代码不那么清晰,增加编译时间,并且更难维护。

我知道Pimpl习语可以解决所有这些问题,但我的问题是,如果我们不想使用Pimpl,可以为一些函数做这样的事情吗?

MyClass.h

class MyClass {
public:
    float foo() const;
}

MyClass.cpp

#include "MyClass.h"
#include "AnotherClass.h"
static float fooPrivate(const AnotherClass& ac) {
    return ac.foo();
}
float MyClass::foo() const {
    return fooPrivate(AnotherClass());
}

在这种情况下,不需要在MyClass.h中包含AnotherClass.h,并且fooPrivate()不能由任何人调用,除非是从MyClass.cpp内部调用,并且在声明之后。我说得对吗?

使用这个有什么注意事项吗?或者当我的程序变得更大时,我会遇到问题吗?

事实上,它不仅可以,我还推荐它。

private函数可以使用,有时必须(访问私有元素时),但它们有一个问题:即使它只是一个声明,它们也会扰乱类定义:类的用户不必关心或暴露于类内部。

另一方面,static函数或在源文件中的匿名命名空间中声明的函数是"免费的"。无论你有多少:

  • 它们不会弄乱页眉
  • 在安腾ABI编译器工具链上(例如),它们不会导致导出符号,从而加快加载时间

不过,如果有一个缺点的话,那就是在那些与安腾相关的工具链上,它们的名称缺失会导致没有调试符号的回溯效果不佳。不过,这可以看作是一个小小的不便。

注意:不能直接访问类的private成员很少是问题,因为类的方法可以很容易地将对这些成员的引用传递给它们。这确实意味着,当构造函数不是公共的时,它们不能构建类的实例

除了轻微的不便之外,没有任何注意事项。很明显,您的静态函数不会是一个类方法。因此,它只能访问公共类成员和方法。

我偶尔会这样做,因为"辅助函数"在类的公共接口中根本没有任何用处。由于无法访问private变量,我尽量减少使用此模式。然而,自由函数是好的,甚至可以说增加了封装。

由于辅助函数只使用类的公共接口,因此可以使用仅在类实现文件中可用的静态函数。

无论如何,您的示例实际上并不需要AnotherClass的定义,轻量级的前向声明就可以了:

class AnotherClass;

此外,我会根据一般原则在这两种情况下标记函数inline,如果它仅由实现使用,并且所有这些都在同一个翻译单元中:
在没有任何缺点的情况下,会有一点机会获得更好的性能/更小的代码。

最新更新