I've implemented my class, lets say class A
using standard PIMPL idiom.
Problem arises when i try overloading <<
operator for my implementation class AImpl
/* A.h */
class A {
public:
...
private:
class AImpl;
AImpl *impl;
}
/* Aimpl.h */
class AImpl {
...
friend ostream &operator <<(ostream &os, const AImpl &impl);
...
}
/* elsewhere.cpp */
ostream &operator <<(ostream &os, const AImpl &impl) {
...
}
Problem stems from overloaded operator not having access to AImpl
class, declared private in A
.
Now i'm in sort of a dilemma over how i should resolve this. One way is declaring overloaded operator friend of class A
too. The other way is making private declaration of class AImpl
public.
Which approach is better and safer?
IMHO you're misusing the PIMPL idiom. The idiom calls for the implementation to be really private, that is AImpl
should not be defined in a header file (for everyone to see), rather it should probably be defined in A.cpp
where also the <<
operator belongs.
If you do that the <<
operator is pointless to declare in header file as well, the only way you would access the PIMPL would be via the containing class anyway. You would define ostream &operator <<(ostream &os, const A &obj)
instead and make that a friend
of A
.
Note that with this approach the AImpl
does not need to be as restrictive about access. It's field and size would only be available from A.cpp
anyway. But if you want to make the internals of AImpl
be private
you could make ostream &operator <<(ostream &os, const A &obj)
a fried
of AImpl
as well.
/* A.h */
class A {
public:
...
private:
class AImpl;
AImpl *impl;
friend ostream &operator <<(ostream &os, const A &obj);
}
/* A.cpp */
class AImpl {
public:
// OR:
friend ostream &operator <<(ostream &os, const A &obj);
...
}
ostream &operator <<(ostream &os, const A &obj) {
AImpl* impl = obj.impl;
...
}