TITLE: Untyped private data and separation of interface and implementation PROBLEM: c-goetze@u-aizu.ac.jp (Christian F. Goetze) One thing that bothers me most in C++ is that you do not have a neat separation between interface and implementation of classes. Usually, you will have the private parts of classes divulged in the header files of that class, with the effect of distracting the reader of the file that is supposed to declare the interface, and the very real nuisance that every internal change will generate a recompile of all parts using that class, even though nothing has changed in the actual interface. So, I am wondering if the following "trick" is a generally accepted C++ idiom: // file A.h class A { private: void *private_data; public: ... // member functions } Of course, you will lose the ability to declare access functions inline, but since I also think it is an abberation to have the implementation of member functions visible in the header files, I do not mind. Good optimizing compilers should do automatic inlining... RESPONSE: kanze@us-es.sel.de (James Kanze US/ESC 60/3/164 #71425) The canonical form of this idiom (sometimes called the Cheshire cat interface) is: class MyTypeImpl ; class MyType { public : // ... private : MyTypeImpl* impl ; } ; MyTypeImpl will be declared in a private header file, and generally, will declare MyType as friend. If MyType is the base of a relatively complex type hierarchy, I will sometimes make things simpler by declaring it as an abstract base class, visibly: class MyTypeImplBase { public : // *Only* pure virtual functions. // And only the public interface. } ; class MyType { public : MyTypeImplBase* operator->() ; MyTypeImplBase const* operator->() const ; protected : MyType( MyTypeImplBase* ptr ) ; private : MyTypeImplBase* impl ; } ; inline MyTypeImplBase* MyType::operator->() { return impl ; } inline MyTypeImplBase const* MyType::operator->() const { return impl ; } The actual MyTypeImpl derives from MyTypeImplBase, adding the data members, and eventually the implementations of some of the virtual functions. Derived classes will also be defined by means of two classes, a (trivially derived) MyTypeDerived, and the actual implementation class. Again, all that is needed in the header file is: class MyTypeDerived : public MyType { public : MyTypeDerived( /* ... */ ) ; } ; The constructor (*not* inline) simply initializes MyType with "new MyTypeDerivedImpl( /* ... */ )"; MyTypeDerivedImpl derives from MyTypeImpl. In addition, any methods which are added to the derived class *will* be defined in MyTypeDerived, as simple forwarding functions.