1

我遇到了一个实现,它以 pimpl 类作为标头并将其包含在 pimpl 实现中。它甚至有意义吗?像这样的东西:

用户界面.h

class UI {

public:

   UI();
   virtual ~UI();

   // bunch of methods
private:

      UIImpl* m_impl;
}

UIImpl.h

class UIImpl
{

public:

  UIImpl( ...) ;
  ......
}

UIImpl.cpp

#include "UIImpl.h" 

UIImpl::UIImpl()

{

  //Actual Implementation
  ...

}

我在想的原因PIMPL是将实现完全隐藏在cpp文件中。有一个标题会破坏目的吗?

4

4 回答 4

2

它们是不同类型的标题。UI.h是“公共的”——它是库外部接口的一部分,供其客户使用。

UIImpl.h是“私人的”,就像现在一样UIImpl.cpp。只要它从未包含在公共标头中,它就可以对客户端保持不可见,就像它.cpp本身一样。

impl将类定义拆分为头文件可能有多种原因。也许其他一些实现类是传递UIImpl&参数。也许只在标题上运行 doxygen 更容易。也许这只是项目政策。

底线是,它仍然是 Pimpl,只要您不发布私有标头。

于 2013-09-02T13:15:29.003 回答
1

我在想的原因PIMPL是将实现完全隐藏在 cpp 文件中。有一个标题会破坏目的吗?

不必要。pIMPL 可用于快速值交换(可能在 C++11/move 语义之前的架构中)、桥接设计模式或任何其他数量的其他原因。

桥梁设计模式的一个例子:

class WinImpl { virtual ~WinImpl() = 0; /* other interfaces here */ };

// different header file(s)
#ifdef WIN32
class WindowsWinImpl: public WinImpl { /* ... */ };
#else
class LinuxWinImpl: public WinImpl { /* ... */ };
#endif

// different header file
class Window { private: WinImpl* pImpl /*= OSWindowFactory::CreateImpl();*/ };

WinImpl在这种情况下,您有一个 pImpl 模型,在类的标题中包含定义是完全可以的Window(因为目的不是隐藏实现,而是抽象它的接口)。

于 2013-09-02T13:14:39.123 回答
1

这样做非常有意义。它允许UIImpl.h修改(和相关的 .cpp),而无需更改依赖于UI.h. 由于UIimpl该类只是作为指针存储[并且可能 UI 本身只能访问该类的公共方法,因此代码UIimpl对 UIimpl 类一无所知UI.h

事实上,您可能需要“UIimpl.h”来允许该类看到该类的公共功能UI

例如

class UIImpl
{

public:

     UIImpl( ...) ;
     void func() { ... }
}

class UI 
{

  public:

   UI();
   virtual ~UI();

   // bunch of methods
   void func() { m_impl->func(); }
   ... 
}

为此,UI需要知道UIimpl该类提供的公共接口。

于 2013-09-02T13:11:03.443 回答
0

是的,这确实有道理。

使用示例:在为多个操作系统开发的代码中,UI.h 从与操作系统无关的代码中可见,但 UIImpl.h 不可见。操作系统相关代码(实现代码)将同时看到头文件 UI.h 和 UIImpl.h

于 2013-09-02T13:10:04.960 回答