obj.c */ #include "obj.h" struct obj { int id; }; /* * The caller will handle allocation. * Provide the required information only */ size_t obj_size(void) { return sizeof(struct obj); } void obj_setid(struct obj *o, int i) { o->id = i; } int obj_getid(struct obj *o) { return o->id; } This example demonstrates a way to achieve the information hiding (encapsulation) aspect of object-oriented programming using the C language. If someone wanted to change the definition of struct obj, it would be unnecessary to recompile any other modules in the program that use the obj.h header file unless the API was also changed. Note that it may be desirable for the functions to check that the passed pointer is not NULL, but such checks have been omitted above for brevity. C++ /* PublicClass.h */ #include <memory> class PublicClass { public: PublicClass(); // Constructor PublicClass(const PublicClass&); // Copy constructor PublicClass(PublicClass&&); // Move constructor PublicClass& operator=(const PublicClass&); // Copy assignment operator PublicClass& operator=(PublicClass&&); // Move assignment operator ~PublicClass(); // Destructor // Other operations... private: struct CheshireCat; // Not defined here std::unique_ptr<CheshireCat> d_ptr_; // Opaque pointer }; /* PublicClass.cpp */ #include "PublicClass.h" struct PublicClass::CheshireCat { int a; int b; }; PublicClass::PublicClass() : d_ptr_(std::make_unique<CheshireCat>()) { // Do nothing. } PublicClass::PublicClass(const PublicClass& other) : d_ptr_(std::make_unique<CheshireCat>(*other.d_ptr_)) { // Do nothing. } PublicClass::PublicClass(PublicClass&& other) = default; PublicClass& PublicClass::operator=(const PublicClass &other) { *d_ptr_ = *other.d_ptr_; return *this; } PublicClass& PublicClass::operator=(PublicClass&&) = default; PublicClass::~PublicClass() = default; The d-pointer pattern is one of the implementations of the . It is commonly used in C++ classes due to its advantages (noted below). A d-pointer is a private data member of the class that points to an instance of a structure. This method allows class declarations to omit private data members, except for the d-pointer itself. As a result, more of the class implementation is hidden adding new data members to the private structure does not affect binary compatibility the header file containing the class declaration only needs to include those files needed for the class interface, rather than for its implementation. One side benefit is that compilations are faster because the header file changes less often. Note, possible disadvantage of d-pointer pattern is indirect member access through pointer (e.g., pointer to object in dynamic storage), which is sometimes slower than access to a plain, non-pointer member. The d-pointer is heavily used in the Qt and KDE libraries. See also Application binary