Sourav
Sourav

Reputation: 157

pimpl for protected member during inheritance

I have a large number of protected member function declared in a `Base class hpp file which is used by the derived class. My Idea is to remove them from the header file to reduce compilation dependency. I thought of using pimpl method for the protected member as well.

I defined a Impl class in Base class cpp file and moved all the protected function inside the Impl class. Further, I did a forward declaration of Impl class in Base class header file as a protected member.

protected:
    class Impl;
    Impl* impl_;

But in doing so, when I am calling the protected funtion using impl_ from derived class, following error occurred in derived class compilation::

error: invalid use of incomplete type ‘class Base::Impl’
    if (false == impl_->EncodeMMMsgHeader(mm_msg_header_)) {
error: forward declaration of ‘class Base::Impl’

I think the error occurs because can't use a forward declaration in any case where the compiler needs contextual information about the class, nor is it of any use to the compiler to tell it only a little bit about the class.

Is there any way by which I could overcome above problem? If not, then can anyone suggest me a better method to achieve my target.

Upvotes: 0

Views: 786

Answers (1)

Jarod42
Jarod42

Reputation: 217348

You might add a layer to reduce dependencies:

From

#include "lot_of_dependencies"

#include <memory>

class MyClass
{
public:
    ~MyClass();
    /*...*/
protected:
    /* Protected stuff */
private:
    struct Pimpl;
    std::unique_ptr<Pimpl> impl;
};

add

MyClassProtectedStuff.h

#include "lot_of_dependencies"

class MyClassProtectedStuff
{
public:
    /* Protected stuff of MyClass */
private:
    // MyClass* owner; // Possibly back pointer
};

and then

MyClass.h

#include <memory>

class MyClassProtectedStuff;

class MyClass
{
public:
    ~MyClass();
    /*...*/
protected:
    const MyClassProtectedStuff& GetProtected() const;
    MyClassProtectedStuff& GetProtected();
private:
    struct Pimpl;
    std::unique_ptr<Pimpl> impl;
    std::unique_ptr<MyClassProtectedStuff> protectedData; // Might be in Piml.
};

And then derived class should include both headers, whereas regular class only include MyClass.h

Upvotes: 1

Related Questions