e.g.
// Implementation.
struct PrivatePoint {
void SomePrivateMethod();
double x;
double y;
}
struct Point : private PrivatePoint {
double DistanceTo(const Point& other) const;
}
This seems similar to the Pimpl idiom. This has two advantages that I really like:
.
Point::DistanceTo(const Point& other) {
SomePrivateMethod();
double dx = other.x - x;
double dy = other.y - y;
return sqrt(dx * dx + dy * dy);
}
vs.
Point::DistanceTo(const Point& other) {
ptr->SomePrivateMethod();
double dx = other.ptr->x - ptr->x;
double dy = other.ptr->y - ptr->y;
return sqrt(dx * dx + dy * dy);
}
Your suggestion has some drawbacks....
The users may couple themselves to the "private" class.
The pimpl idiom's primary purpose is as a compilation firewall, allowing the private members to be specified in the implementation file, and therefore to be changed without touching the header and necessitating / triggering client recompilation, as distinct from just relinking, which is faster, and may not even require any actions involving the client app if the update is to a dynamically loaded library. You lose these benefits.
SomePrivateMethod is testable. If SomePrivateMethod were instead declared as private in Point, you wouldn't be able to call it from tests. If you declared it as public or protected in Point, tests would be able to call it, but so would regular users of Point.
There are other convenient if hackish options: for example - you can declare friendship with testing code, or use the preprocessor to build in a testing mode that exposes data.