While trying to remove all implementation details from a header file I decide to use and try out PIMPL idiom. The majority if not all examples, e.g. cppreference, I've seen use levels of indirection which reason I can't understand besides encapsulation. The examples always come with this flavor pattern.
Typical
//A.hpp
class A
{
public:
A(int);
//More non-static class methods
void set(int);
private:
struct a_impl;
std::unique_ptr<struct a_impl> pimpl;
};
//A.cpp
struct A::a_impl
{
private:
int i;
public:
a_impl(int i) : i{i}{}
//More non-static implementation class methods
void set(int i) {this->i = i;}
};
A::A(int i) : std::make_unique<struct a_impl>(i) {}
A::set(int i) {pimpl->set(i);} //????
A:://More indirect calls to non-static member functions through pointer
At certain point I start wondering why do I need all this level of complexity and indirection if we are talking about implementation. Why not something simplest without all those indirect calls.
Why not ?
//A.hpp
class A
{
public:
A(int);
//.....
void set(int);
private:
struct a_impl;
std::unique_ptr<struct a_impl> pimpl;
};
//A.cpp
struct A::a_impl
{
int i;
}
A::A(int i) : std::make_unique<struct a_impl>() { pimpl->i = i; }
A::set(int i) { pimpl->i = i; } //!!!!
What I would like to clarify:
1-Are all this samples presented this way just for a matter of education and good encapsulation practices?
2-Is there any other good reason I'm missing to add this level of complexity and overhead besides question 1?
3-Or what I put out as an alternative isn't PIMPL idiom?