It is fine to reveal implementation when it's intentional, necessary, and carefully controlled. However, don't make such a decision lightly: it is quite easy to do it by accident.
For example, public or protected data members or inline functions that access private data members reveal an important aspect of your implementation. If developers use those functions (not just application developers, but any programmer building on top of the Taligent Application Environment), the system's requirement of binary compatibility means that you can't:
constpointer (at least the caller can't change the member) or have a pair of member functions along the lines of "I want to use this subobject" and "I'm done with this subobject." This latter variety is especially desirable because it gives you the flexibility to synthesize the object on request. If the functions are the constructor or destructor of an accessor object, you can let C++ handle exceptions for you (see "Exception handling" on page 74).
It is also possible to achieve the efficiency of pointers while retaining copying semantics (see "Surrogate objects" on page 91).