title: C++ Communicating private data from opaque pointer
body: <p>I've recently learned about opaque pointers in C++.  I've started using them to hide private members that are platform specific.  Such as references to definitions in <code>&lt;windows.h&gt;</code> etc.</p>
  
  <p>Now, I have several systems that build off each other and need to intercommunicate.  For example, Direct3D needing a window handle (HWND).  I do not want to expose platform definitions to my core system, however my subsystems need to communicate that data.</p>
  
  <p>I'm exposing the opaque data and allowing access through a void pointer.  This allows access to all private data.</p>
  
  <p>Example usage (main.cpp):</p>
  
  <pre><code>// System:: namespace is my platform specific code
  System::Window window;
  System::DirectX::Direct3D9 gfxcontext(window);
  </code></pre>
  
  <p>Window definition (System/Window.h):</p>
  
  <pre><code>class Window
  {
      WindowData* data; // Opaque pointer
  public:
      void* getHandle() const; // returns an HWND handle
      Window();
      ~Window();
  }
  </code></pre>
  
  <p>How to retrieve useful data (Direct3D9.cpp):</p>
  
  <pre><code>#include "Window.h"
  
  Direct3D9::Direct3D9(const Window&amp; _window)
  {
      HWND windowHandle = *(HWND*)_window.getHandle();
      // [...]
      pp.hDeviceWindow = windowHandle;
  }
  </code></pre>
  
  <p>However, this code works!:</p>
  
  <pre><code>*(HWND*)_window.getHandle() = 0; // changes HWND in WindowData to NULL!
  </code></pre>
  
  <p>Is there a way to communicate the platform specific information between subsystems without exposing it to my independent code -and- keeping private data private?</p>
  
  <hr>
  
  <p><em>Edit</em> current WindowData implementation</p>
  
  <pre><code>struct Window::WindowData
  {
      static LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM);
      HWND windowHandle;
      WNDCLASSEX windowClass;
      HINSTANCE processInstance;
  };
  </code></pre>
  
  <p>The HWND is used by DirectX in the presentation parameters (<code>D3DPRESENT_PARAMETERS::hDeviceWindow</code>)</p>