An opaque data type is a type whose implementation is hidden from the user.  The only way to use opaque data type is via an abstract pointer interface exposed in the API. A famous example is the FILE data type in the C standard I/O library.

The advantage of opaque data type is that user does not need to worry about the implementation details and data members of the type. All that is needed by the user, are the interface functions to manipulate the type. Even if the internal details of the data type are changed, the user does not need to change the code using it. It is also useful in case when different vendors of a library have different implementation of the same data type, but they appear same to the user.

To create an opaque data type in C/C++, we just have to declare the type in a header file (say header.h) and also provide a user friendly pointer interface declaration.

<br />#pragma once</p><p>//Declaration of data type<br />struct _myType;</p><p>//Declaration of user interface pointer.<br />typedef struct _myType* myType;<br />

We may also declare some functions to manipulate the variables of the data type.

<br />//Type manipulation functions' declaration<br />myType createMyType();<br />void deleteMyType(myType arg);<br />void copyMyType(myType* destination, myType* source);<br />

Now the actual part is to define and implement the data type in a source file (say source.cpp). Once the file is compiled, implementation would be completely hidden from the user.

<br />#include&quot;header.h&quot;<br />#include&lt;stdlib.h&gt;</p><p>//The structure (struct _myType) is<br />//actually defined here in source.cpp.<br />struct _myType<br />{<br />int x;<br />int y;<br />int z;<br />};<br />

Define the functions in the same source file. You can move the functions to another source file (say source2.cpp), but the type definition should be visible to the functions, so #include"source.cpp" in source2.cpp.

<br />myType createMyType()<br />{<br />myType ptr;</p><p>#ifdef __cplusplus<br />ptr = new _myType;<br />#else<br />ptr = malloc(sizeof(struct _myType));<br />#endif</p><p>return ptr;<br />}</p><p>void deleteMyType(myType arg)<br />{<br />#ifdef __cplusplus<br />delete arg;<br />#else<br />free(arg);<br />#endif<br />}</p><p>void copyMyType(myType* destination, myType* source)<br />{<br /> (*destination)-&gt;x = (*source)-&gt;x;<br /> (*destination)-&gt;y = (*source)-&gt;y;<br /> (*destination)-&gt;z = (*source)-&gt;z;<br />}<br />

We can use the data type in our code like this:

<br />#include&quot;header.h&quot;</p><p>void main()<br />{<br />    myType t1 = createMyType();<br />    myType t2 = createMyType();</p><p>    copyMyType(&amp;t2,&amp;t2);</p><p>    deleteMyType(t1);<br />    deleteMyType(t2);<br />}</p><p>

You can download this example which demonstrates how to create and use an opaque data type.