Component objects contain data specific to the object and one or more interface implementations. The data is private and inaccessible from outside the object, while the interface implementations are public and you can access them through pointers.
Because interfaces are a binary standard, interface implementation is language independent. However, C++ is the preferred language because it supports many of the object-oriented concepts inherent in OLE. Using a procedural language such as C involves extra work, as summarized below:
To overcome this difference, OLE provides a mechanism that lets C developers declare VTBLs as constants. To do so, place the following statement before the #include statement for the "ole2.h" header file:
#define CONST_VTABLE
For example, the following C++ code sample defines an implementation of IUnknown::QueryInterface. The method name is QueryInterface and there are two parameters: a REFIID and a pointer to where to return the requested interface instance.
CUnknown::QueryInterface (REFIID riid, LPVOID * ppvObj);
A similar C implementation would require a more complex name and an additional first parameter to indicate the object owning the method:
IUnknown_Doc_QueryInterface (LPUNKNOWN pUnk, REFIID riid,
LPVOID * ppvObj);
The following sections demonstrate how to declare a component object in a few typical ways: using C nested data structures, C++ nested classes, and C++ multiple inheritance. The demonstration object, called CObj, derives from IUnknown and supports two interfaces that also derive from IUnknown, InterfaceA and InterfaceB. CObj's private data includes a pointer to another component object in the application (m_pCDoc), a count of all the external references to the object (m_ObjRefCount), and pointers to two interfaces implemented by other component objects and used by CObj (m_pOleObj and m_pStg). All object members use the m_ prefix to make it easy to distinguish between member variables and other variables.