C++,私有函数真的需要在 header 文件中吗?

C++, do private functions really need to be in the header file?

我一直认为 header 文件是一种描述 class 的 'public interface',在这种情况下最好将私有字段和函数保留在 cpp 文件中.

我知道私有字段需要在 header 中,以便其他 classes 可以知道 class 的实例将消耗多少内存,但它发生了当我正要编写一个私有辅助函数时,我知道这个函数可以是静态的,在这种情况下根本不需要它是 'part of the class',它可以很容易地成为class 定义的 .cpp 文件。

然后我想到 all 私有函数可能 re-written 通过接受 [=47] 是静态的=] 到 class 字段,而不是期望在 class.

中定义

这将消除在 header 文件中声明任何私有函数的需要。

我确实喜欢遵循约定,所以现在我想问一下,non-static 私有函数 应该[=38= 是否被认为是 C++ 中的既定约定] 在 header 文件中?静态函数或静态常量呢?

编辑:我将放入一些代码来解释我的意思:

.h 文件:

#ifndef SOME_CLASS_H
#define SOME_CLASS_H

class SomeClass
{
private:
    int x;
public:
    void combineWithX(int y);
};

#endif

.cpp 文件

#include "SomeClass.h"

void someHelper(int* x)
{
    *x = (*x) + 1;
}

void SomeClass::combineWithX(int y)
{
    someHelper(&x);
    x += y;
}

请注意,cpp 文件中的 someHelper(int* x) 实质上引用了私有成员 x,但不是直接引用,因此不需要出现在 header 中。我想知道这种事情是否被认为是 'bad style'

我同意需要在头文件中公开实现细节是一个问题;它干扰了接口和实现的分离。

如果这些函数需要访问私有成员变量,则将私有辅助函数移动为 .cpp 文件中的自由函数(我想这就是您所说的 "static" 的意思)将不起作用。

您可能有兴趣查看 pImpl idiom (more)

私有辅助函数可以从 public 头文件中隐藏,方法是将它们移动到内部 class。这是可行的,因为内部 class 被认为是 class 的一部分并且可以访问周围 class 的私有成员。

与 PImpl 习惯用法不同,它没有任何动态分配或间接惩罚。 editing/refactoring 私有函数的编译时间应该更快,因为不需要重新编译所有文件,包括 public 头文件。

示例:

public.h 文件

#ifndef SOME_CLASS_H
#define SOME_CLASS_H

class SomeClass
{
private:
    // Just forward declaring in public header.
    struct Private;
    int x;
public:
    void combineWithX(int y);
};

#endif

在 .cpp 文件中

#include "SomeClass.h"

// Declare all private member functions of SomeClass here
struct SomeClass::Private
{
  static void someHelper(SomeClass& self)
  {
    self.x = self.x + 1;
  }
};

void SomeClass::combineWithX(int y)
{
    Private::someHelper(*this);
    x += y;
}

怎么样

// MyClass.h -

MyClass {
public:
   // public stuff..

#ifdef mynamespace_myclass_p
private:
   // private stuff..
#endif // mynamespace_myclass_p

}

// MyClass.cpp - 

#define mynamespace_myclass_p
#include "MyClass.h"

// implementation code..

嗯,但是你的 headers 仍然堆满了私人物品。

Headers 太痛苦了。我可能是错的,但目前我觉得 headers 是所有 C++ 中痛苦/有用比率最大的东西。当你用 C++ 编程时,你基本上必须在至少两个地方维护你所有的方法签名,如果你不希望你的 public headers 被私有的东西弄得乱七八糟,你几乎必须有 2 headers 的版本,这意味着至少在 3 个地方保留您的签名!再加上任何被证明是需要的前锋声明。说真的,它们带来的麻烦远远超过它们的价值。

我真的很期待看到 C++20 的模块系统如何发挥作用。这可能是一个巨大的福音。我们已经等了将近 5 年了。