Search code examples
c++inheritanceooppimpl-idiom

Pimpl idiom with inheritance


I want to use pimpl idiom with inheritance.

Here is the base public class and its implementation class:

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

And I want to be able to create the derived public class with its implementation class:

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*/};
};

But I can't use pAimpl in B because it is A's private.

So I see some ways to solve it:

  1. Create BImpl* pBImpl member in B, and pass it to A with additional A constructor, A(AImpl*).
  2. Change pAImpl to be protected (or add a Get function), and use it in B.
  3. B shouldn't inherit from A. Create BImpl* pBImpl member in B, and create foo() and bar() in B, that will use pBImpl.
  4. Any other way?

What should I choose?


Solution

  • 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*/};
    };