In languages like Java, you can declare a class without a modifier so it will only be visible inside the same package. I need to do something similar in C++. I am trying to create an API that will be a library to be used in other applications. After asking this question on programmers Stackexchange, I have decided to use some sort of handle, which will just be an unsigned integer that is passed to an API function, which will then pass it to a class that will look it up in some sort of table and return a pointer to the object the handle represents, back to the function. The API function will then be allowed to operate on the pointer, but without the public ever having access to the pointer.
The problem is, I would like the class that handles the handles to not be visible to the public (even though the public won’t have an instance of the class that contains the handles), as it is only needed inside the API functions. Also, I wanted this handle class to be a template (only needed for compiling the API), because I would most likely have handles representing different types of classes (although I could probably get away with one table containing void pointers, but it seems a little unsafe). I cant hide the class in a .cpp file, because it would be needed in multiple .cpp files that compose the API.
Also, I was thinking about using the pimpl idiom in any classes that have public functions, that way if there were any private functions in them that needed a parameter related to one of my classes hidden from the public, a header file including hidden classes would not need to be included with the API libraries for the API user to be able to compile the program.
So what would be the best way to hide classes that are only needed among other classes (spread across multiple .h and .cpp files) inside the API its self, from the outside world?
You can indeed use the PIMPL idiom; just write a forward declaration of the type and use a (smart) pointer to it as a member. That should take care of header files.
For the implementation, just have a separate header file that is included by the implementation of the library but not by any part of the interface. Example: