在查看某些代码时,我遇到了以下内容:
.h文件
class ExampleClass
{
public:
// methods, etc
private:
class AnotherExampleClass* ptrToClass;
}
.cpp文件
class AnotherExampleClass
{
// methods, etc
}
// AnotherExampleClass and ExampleClass implemented
在c ++中工作时这是一种模式还是有益的?由于该类没有分成另一个文件,这个工作流程是否会促进更快的编译时间?
或者这只是这个开发者的风格?
答案 0 :(得分:25)
这被称为pImpl Idiom,柴郡猫技术或编译防火墙。
优点:
- 更改类的私有成员变量不需要重新编译依赖于它的类,从而使时间更快,并且 FragileBinaryInterfaceProblem减少了。
- 头文件不需要#include私有成员变量中“按值”使用的类,因此编译时间更快。
- 这有点像SmallTalk自动处理类的方式...更纯粹的封装。
缺点:
- 为实施者做更多工作。
- 不适用于需要按子类访问的“受保护”成员。
- 读取代码有点困难,因为某些信息不再出现在头文件中。
- 由于指针间接,运行时性能略有下降,特别是如果函数调用是虚拟的(间接分支的分支预测通常很差)。
Herb Sutter的“Exceptional C ++”书籍也详细介绍了这种技术的适当用法。
答案 1 :(得分:11)
最常见的例子是使用PIMPL模式或类似技术。不过,还有其他用途。通常,C ++中的区别.hpp / .cpp相当(或者至少可以是)公共接口与私有实现之一。如果一个类型仅用作实现的一部分,那么这是一个很好的理由不将它导出到头文件中。
答案 2 :(得分:7)
除了可能是PIMPL习惯用法的实现之外,还有两个可能的原因:
C ++中的对象无法修改其this
指针。因此,他们无法在中途使用中更改类型。但是,ptrToClass
可以更改,允许实现delete
本身并将其自身替换为AnotherExampleClass
的另一个子类的另一个实例。
如果AnotherExampleClass
的实现依赖于某些模板参数,但ExampleClass
的接口没有,则可以使用从AnotherExampleClass
派生的模板来提供实现。这会隐藏来自接口类用户的必要但内部类型信息的一部分。