smörkex
smörkex

Reputation: 336

C++ Inheritance in the Pimpl idiom

Let's say I have a class B and a class A : public B which inherits from B. I want to expose the methods of A, which call some methods in B.

Now I want to expose these methods in the pimpl idiom - I'm really not sure how to do this:

Thanks

Edit: Here is an example code snippet - is this correct?

test.hpp

#include <iostream>

class B {
private:
    class impl;
    std::unique_ptr<impl> pimpl;

public:
    B();
    ~B();
    B(B&&) = default; 
    B(const B&) = delete;
    B& operator=(B&&);
    B& operator=(const B&) = delete;

    void my_func() const;
};

class A : public B {
private:
    class impl;
    std::unique_ptr<impl> pimpl;

public:

    A();
    ~A();
    A(A&&) = default; 
    A(const A&) = delete;
    A& operator=(A&&);
    A& operator=(const A&) = delete;

    void access_my_func();
};

test.cpp

#include "test.hpp"

// Implementation of B
class B::impl
{
public:
    impl() {};

    void impl_my_func() { 
        std::cout << "impl_my_func" << std::endl;
        return; 
    };
};

// Constructor/Destructor of B
B::B() : pimpl{std::make_unique<impl>()} {};
B::~B() = default;
B& B::operator=(B&&) = default;

// Exposed method of B
void B::my_func() const {
    std::cout << "B::my_func" << std::endl;
    pimpl->impl_my_func();
    return; 
};


// Implementation of A
class A::impl
{
public:
    impl() {};

    void impl_access_my_func(const A& a_in) {
        std::cout << "impl_access_my_func" << std::endl;
        a_in.my_func();
        return;
    };
};

// Constructor/Destructor of A
A::A() : pimpl{std::make_unique<impl>()} {};
A::~A() = default;
A& A::operator=(A&&) = default;

// Exposed method of A
void A::access_my_func() {
    std::cout << "A::access_my_func" << std::endl;
    pimpl->impl_access_my_func(*this);
    return;
};




// Later in the main.cpp file
int main() {

    // Make an object
    A my_A_object;
    my_A_object.access_my_func();

    return 0;
};

Upvotes: 1

Views: 2275

Answers (1)

Christopher Oezbek
Christopher Oezbek

Reputation: 26493

If you subclass A from B then, A should be able to call the interface of class B. It should not have to rely on its implementation.

The Pimpl-Ideom is just a way to deal with the limitations of C++, that you cannot split the declaration of private, protected and public parts of your class. Since you would not want to expose the private parts of your class to your class users and don't want to expose the protected parts to users who don't want to subclass, the Pimpl-Ideom moves these parts away from the header file.

To answer your question:

  • class A must subclass B, that is what OOP is about.
  • class A::impl should not need to rely on B::impl to get its job done.
  • If you want to go to extremes you could envision a B::protected_impl which A::impl could subclass. For this to work you must create a separate header with the protected_impl declaration so that A::impl can use it.

Upvotes: 1

Related Questions