C++私有函数真的需要在头文件中吗
Do C++ private functions really need to be in the header file?
我一直认为头文件是一种描述类的"公共接口",在这种情况下,最好在.cpp文件中保留私有字段和函数。
我知道私有字段需要在头中,这样其他类就可以知道一个类的实例将消耗多少内存,但当我正要写一个私有助手函数时,我突然想到,这个函数可以变成静态的,在这种情况下,它根本不需要是"类的一部分",它可以很容易地成为类定义的.cpp文件中的一个常规函数。
然后我想到所有私有函数都可以通过接受对类字段的指针/引用而不是期望在类中定义来重写为静态函数。
这将消除在头文件中声明任何私有函数的需要。
我确实喜欢遵循惯例,所以在C++中,非静态私有函数应该在头文件中,这被认为是一个既定的惯例吗?静态函数或静态常数呢?
我要输入一些代码来解释我在上得到了什么
.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,但不是直接引用,因此不需要出现在标头中。我想知道这种东西是否被认为是"糟糕的风格"。
通过将私有助手函数移动到内部类,可以从公共头文件中隐藏它们。这是因为内部类被认为是类的一部分,并且可以访问周围类的私有成员。
与PIMPL习惯用法不同,它没有任何动态分配或间接惩罚。编辑/重构私有函数时,编译时间应该更快,因为不需要重新编译所有文件,包括公共头。
示例:
公共.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;
}
我同意需要在头文件中公开实现细节是一个问题;它干扰了接口和实现的分离。
如果.cpp
文件中的私有助手函数需要访问私有成员变量,则将这些函数移动为自由函数(我认为这就是您所说的"静态")将不起作用。
您可能有兴趣了解pImpl习惯用法(更多)
有时我看到人们使用两个不同的头,一个公共头和一个私有头,比如:
// SomeClass.h - - - -
SomeClass
{
public:
// public functions
}
// SomeClass_.h - - - -
SomeClass
{
public:
// public functions
private:
// private functions
}
// SomeClass.cpp - - - -
#include "SomeClass_.h"
// SomeClass implementation
这样做的优点是,公共头不会被私有函数声明弄得一团糟,但它需要开发人员维护每个函数签名的3个副本。
长期以来,头文件一直被许多人认为是有问题的,这不仅是因为与它们相关的维护开销增加,还因为它们对构建环境的影响。编写代码或设置构建设置很容易导致系统或外部标头级联编译失败,从而导致大量潜在的模糊错误。C++20模块是一个可能值得探索的替代方案。
- C++ gmock - 我们如何在单元测试 cpp 文件中读取/获取 cpp 文件函数的参数值
- 使用其他头文件函数的头文件
- 创建文件函数是否可以打开仅在WinObj实用程序中的全局目录下列出的设备的句柄?
- 如何指定创建文件函数获取未缓存的结果?
- 标准库头文件函数原型的实现是如何用 c++ 编写的?
- 如何将类对象作为对另一个头文件函数的引用传递
- 读取文件函数lpbuffer和字节以读取澄清
- C++ - 未定义的对多个文件函数的引用
- 使用C++的可视 Unicode 文件函数
- C 创建文件函数错误
- WinAPI 创建文件函数 2.
- 具有CREATE_ALWAYS处置的创建文件函数
- 重写c库文件函数
- 如何使用客户端调用堆栈中的地址从 PDB 检索文件/函数/行号?
- 通过头文件函数将遍历的数据从二进制搜索树加载到Vector中
- 需要帮助无法弄清楚为什么我的头文件函数声明不起作用
- 是否可以在不使用文件函数的情况下使用代码块从文件运行某些用例测试?
- 如何用c++文件函数读写8位整数单位形式的数据
- 在c++中读文件函数如何识别文本文件的结束
- 使用Windows API的c++文件函数