I'm writing a C++ library which needs to creates a complex object (D), but return to the user of my library a pointer to a simplified object (B) (hiding many of the methods of the complex object). I have decided to implement this by returning a pointer to a simplified base class (B), and adding all of my complex functionality to a derived class (D) as follows:
class B {
virtual void simple() = 0;
}
class D : public B {
void simple() { cout << "visible simple stuff" ; }
void complex() { cout << "invisible complex stuff" ; }
}
Internally I create my object D, but I return an upcast pointer as follows:
D Derived;
B *Bptr = &Derived;
return Bptr;
Is this the right way to hide functionality from the user, while making all of the additional functionality visible within the library?
Is hiding the .h file for class D the only way to prevent my library users from accessing the D methods? (Downcasting back to a D class) I will be releaseing the library as open source, so the user of the library could access the D class definition.
About question #1: yes, if you provide a factory method along with your 'simple' interface:
class B {
public:
static B * create();
virtual void simple() = 0;
};
in B's implementation file (cpp):
B *B::create()
{
return new D(); //or whatever 'hidden' implementation
}
About your #2: hiding functionality means simplification in the first place, and is intended as a favour toward the library users, not a punishing constraint. So, hide the D class entirely and let the (good) users be happy with it.