为什么要将类放在实现文件中?

时间:2014-08-13 15:36:34

标签: c++ class

在查看某些代码时,我遇到了以下内容:

.h文件

class ExampleClass
{
public:
    // methods, etc
private:
    class AnotherExampleClass* ptrToClass;
}

.cpp文件

class AnotherExampleClass
{
    // methods, etc
}

// AnotherExampleClass and ExampleClass implemented 

在c ++中工作时这是一种模式还是有益的?由于该类没有分成另一个文件,这个工作流程是否会促进更快的编译时间?

或者这只是这个开发者的风格?

3 个答案:

答案 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派生的模板来提供实现。这会隐藏来自接口类用户的必要但内部类型信息的一部分。