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

Gho*_*314 25 c++ standards conventions

我一直认为头文件是一种描述类的"公共接口",在这种情况下,最好将私有字段和函数保存在cpp文件中.

我知道私有字段需要在头文件中,以便其他类可以告诉一个类的实例将消耗多少内存,但是当我要写一个私有帮助函数时,它就出现了,这个函数可以被创建静态,在这种情况下根本不需要它是"类的一部分",它可以很容易地成为类定义的.cpp文件中的常规函数​​.

然后我想到,通过接受指向类字段的指针/引用而不是期望在类中定义,所有私有函数都可能被重写为静态函数.

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

我喜欢遵循约定所以现在我想问一下,它是否被认为是C++中的既定约定,非静态私有函数应该在头文件中?静态函数或静态常量怎么样?

编辑:我将提供一些代码来解释我所得到的:

.h文件:

#ifndef SOME_CLASS_H
#define SOME_CLASS_H

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

#endif
Run Code Online (Sandbox Code Playgroud)

.cpp文件

#include "SomeClass.h"

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

void SomeClass::combineWithX(int y)
{
    someHelper(&x);
    x += y;
}
Run Code Online (Sandbox Code Playgroud)

请注意,someHelper(int* x)在cpp文件中引用私有成员x,但不是直接引用,因此不需要出现在标题中.我想知道这种事情是否被认为是"坏风格"

bal*_*lki 19

只需要PImpl习语

  1. 如果你需要将私有成员'变量'移出公共标题(为了维护新版本的二进制兼容性 - 如果你不知道这意味着什么,那么它可能不是一个问题)
  2. 如果该设计使其更容易理解

如果您只想将私有成员'函数'移出公共头,那么使用内部类就足够了.这没有像PImpl惯用语那样的重定向惩罚.

公共.h文件

#ifndef SOME_CLASS_H
#define SOME_CLASS_H

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

#endif
Run Code Online (Sandbox Code Playgroud)

在.cpp文件中

#include "SomeClass.h"

/** Declare all private member functions of SomeClass here
    This class can access not only private members of SomeClass
    but also friends of SomeClass. */
struct SomeClass::Private
{
  static void someHelper(SomeClass& self)
  {
    self.x = self.x + 1;
  }
};

void SomeClass::combineWithX(int y)
{
    Private::someHelper(*this);
    x += y;
}
Run Code Online (Sandbox Code Playgroud)

SomeClass::Private可以拥有任何数量的辅助函数,它们可以完全访问所有私有/朋友SomeClass,而不必在头文件中声明它们中的任何一个.

  • 难道“Private”不需要声明为友元才能访问“SomeClass”的私有成员吗?`friend 结构私有`。我刚刚检查了您的代码是否可以编译并且确实可以编译,但我不明白为什么。普通的嵌套类/结构不会获得其封闭类的任何特殊权限。 (2认同)
  • 我看到我在混淆范围设定规则。事实证明,嵌套类与定义的其他数据成员具有相同的访问级别限制,因此它可以访问封闭类的私有成员。我当时想的是相反的事实,即封闭类无法访问嵌套类的内部。这是由标准(cpp17 n4659)-12.2.5涵盖的嵌套类声明,正向声明和访问权限所保证的。很棒的论坛帖子:http://www.cplusplus.com/forum/general/181016/打算利用它,因为它更好地封装了私有成员函数 (2认同)

M.M*_*M.M 9

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

将私有帮助函数移动到.cpp文件中的自由函数(我认为这是"静态"的意思)如果这些函数需要访问私有成员变量,则不起作用.

你可能有兴趣看看pImpl成语 (更多)