Pimpl成语与继承

Igo*_*Oks 16 c++ oop inheritance pimpl-idiom

我想用继承的pimpl习语.

这是基础公共类及其实现类:

class A
{
    public:
      A(){pAImpl = new AImpl;};
      void foo(){pAImpl->foo();};
    private:
      AImpl* pAImpl;  
};
class AImpl
{
    public:
      void foo(){/*do something*/};
};
Run Code Online (Sandbox Code Playgroud)

我希望能够使用其实现类创建派生公共类:

class B : public A
{
    public:
      void bar(){pAImpl->bar();};    // Can't do! pAimpl is A's private.
};        

class BImpl : public AImpl
{
    public:
      void bar(){/*do something else*/};
};
Run Code Online (Sandbox Code Playgroud)

但我不能在B中使用pAimpl,因为它是A的私有.

所以我看到一些解决方法:

  1. 在B中创建BImpl*pBImpl成员,并使用附加的A构造函数A(AImpl*)将其传递给A.
  2. 更改要保护的pAImpl(或添加Get函数),并在B中使用它.
  3. B不应该继承自A.在B中创建BImpl*pBImpl成员,并在B中创建foo()和bar(),这将使用pBImpl.
  4. 还有其他方法吗?

我应该选择什么?

Igo*_*Oks 7

class A
{
    public:
      A(bool DoNew = true){
        if(DoNew)
          pAImpl = new AImpl;
      };
      void foo(){pAImpl->foo();};
    protected:
      void SetpAImpl(AImpl* pImpl) {pAImpl = pImpl;};
    private:
      AImpl* pAImpl;  
};
class AImpl
{
    public:
      void foo(){/*do something*/};
};

class B : public A
{
    public:
      B() : A(false){
          pBImpl = new BImpl;
          SetpAImpl(pBImpl);
      };
      void bar(){pBImpl->bar();};    
    private:
      BImpl* pBImpl;  
};        

class BImpl : public AImpl
{
    public:
      void bar(){/*do something else*/};
};
Run Code Online (Sandbox Code Playgroud)

  • 当 AImpl 和 BImpl 位于单独的 .cpp 文件中时,我认为这不起作用。BImple 不应该能够从 AImple 继承——因为 AImple 是定义 BImple 的 .cpp 中的不完整类型。 (2认同)
  • @javaLover 是的,但我认为这个想法是将实现细节隐藏在 cpp 中。将 impl 放入标头中并不会隐藏它们。虽然我认为仍然会加快编译时间,因为包括 AImpl.h 和 BImpl.h 的唯一文件是 A.cpp 和 B.cpp (2认同)