为什么要把类放在实现文件中呢?
Why would you want to put a class in an implementation file?
在查看一些代码时,我遇到了以下问题:
. h文件class ExampleClass
{
public:
// methods, etc
private:
class AnotherExampleClass* ptrToClass;
}
. cpp文件class AnotherExampleClass
{
// methods, etc
}
// AnotherExampleClass and ExampleClass implemented
在c++中工作时,这是一种模式还是有益的东西?由于类没有分解到另一个文件中,这个工作流程是否可以提高更快的编译时间?
或者这只是这个开发者的风格?
这被称为pImpl习惯用法、柴郡猫技术或编译防火墙。
好处:
- 更改类的私有成员变量不需要重新编译依赖于它的类,从而使时间更快,并且FragileBinaryInterfaceProblem减少
- 头文件不需要#include在私有成员变量中"按值"使用的类,因此编译时间更快。
这有点像SmallTalk自动处理类的方式…更纯的封装。缺点:
- 实现者的更多工作。
- 对于需要子类访问的"protected"成员不起作用。
- 有点难读代码,因为一些信息不再在头文件。
- 运行时性能会因为指针间接而受到轻微的损害,特别是如果函数调用是虚拟的(间接分支的分支预测通常很差)。
Herb Sutter的《Exceptional c++》一书也详细介绍了如何正确使用这种技术。
最常见的例子是在使用PIMPL模式或类似技术时。不过,它还有其他用途。通常,c++中.hpp/.cpp的区别更像是(或者至少可以是)公共接口与私有实现的区别。如果一个类型只是作为实现的一部分使用,那么就有理由不把它导出到头文件中。
除了可能是PIMPL习惯用法的实现之外,这样做还有两个可能的原因:
c++中的对象不能修改它们的this
指针。因此,它们不能在使用过程中改变类型。然而,ptrToClass
可以改变,允许delete
本身的实现,并将其替换为AnotherExampleClass
的另一个子类的另一个实例。
如果AnotherExampleClass
的实现依赖于某些模板参数,而ExampleClass
的接口不依赖,则可以使用从AnotherExampleClass
派生的模板来提供实现。这对接口类的用户隐藏了部分必要的内部类型信息。
相关文章:
- 在实现文件中使用头文件的通用 lambda
- 在文件上实现迭代器
- C++头文件和类实现出现问题
- 在文件夹迭代上实现 RAII
- 如何使用命令提示符、记事本和 MinGW 使用主文件、头文件和实现文件编译C++程序?
- 用于 Windows 写入临时文件的 mkstemp() 实现
- 类中的数组变量C++导致"was not declared in this scope"实现文件的一个函数中错误,但在构造函数中不会导致错误
- Linux 源代码中普通磁盘文件的"轮询"功能在哪里实现?
- 在 *.cpp 文件中实现的 c++ 函数/方法永远不会内联扩展吗?
- 在实现文件中使用模板参数声明方法
- 在头文件中使用opencv类型来实现未定义的标识符
- 模板实现文件中的匿名命名空间
- 创建单独的实现文件和头文件
- 多文件类实现Cpp
- Reader类实现中的文件读取错误
- MEX文件实现特征库伪内函数崩溃
- openssl rc4 命令行加密和 cpp 文件实现 rc4 之间的区别
- 从其他头文件实现结构
- c++头文件-实现-头文件-实现依赖链
- 内存映射文件实现