In exposing the C++ (or Java) interface of a library, one has to provide the "private" fields of classes, and this is understable, because the compiler needs to know the structure of the class, in order to be able to compute, for example, sizeof().
But why this is needed and how could be alleviated? Because, for me, it appears as a breach in the encapsulation concept: why the user shall worry or have access to something that is considered to be private?
One solution would be to define a size() function for each object, but this will be burdensome at runtime.
Still, one language (eC/ecere) claims that [1]:
"Library developers don't need to worry about the private content of the class definition being seen by the end user, only what is declared public will be visible"
How is that achieved in eC and how could similar be implemented in Java or C++?
Just because the programmer or the compiler can "see" a private type, doesn't mean it violates "encapsulation". Consider encapsulation as a "contract" (you're not supposed to use it, but you can still see it).
... HOWEVER ...
the answer to your question, if you really want to "hide" the underlying representation, is to use opaque pointers:
Here's an example in C++:
http://www.tilander.org/aurora2/Stupid_Cpp_Tricks/index.html
One of the early books I bought on C++ was James Coplien's 'Acid Book' (as Meyers calls it). Much of the stuff in there is today more bread and butter things, although it you haven't read it, you should. One of the things James (or Jim, how nice of a name is that) introduced was the Pimpl idom. Private Implementation is a happy interpretation of the weird name, the more plausible is pointer to implementation. In simple terms it's a compiler firewall, or an opaque type that effectively hides the implementation of any class from the outside.
// in the header
class Foo
{
public:
Foo();
~Foo();
private:
struct Pimpl; // forward declaration to internal structure
Pimpl* m; // opaque pointer to actual data
};
// in the cpp file
struct Foo::Pimpl
{
std::string name;
};
Foo::Foo()
: m( new Pimpl)
{
}
Foo::~Foo()
{
delete m;
}