最近,我了解了C++中的不透明指针。我已经开始使用它们来隐藏特定于平台的私有成员。例如引用<windows.h>中的定义等。
现在,我有几个相互建立起来的系统,需要相互交流。例如,Direct3D需要一个窗口句柄(HWND)。我不想向我的核心系统公开平台定义,但是我的子系统需要通信这些数据。
我正在公开不透明的数据,并允许通过一个空指针访问。这允许访问所有私有数据。
示例用法(main.cpp):
// System:: namespace is my platform specific code
System::Window window;
System::DirectX::Direct3D9 gfxcontext(window);窗口定义(System/Window.h):
class Window
{
WindowData* data; // Opaque pointer
public:
void* getHandle() const; // returns an HWND handle
Window();
~Window();
}如何检索有用的数据(Direct3D9.cpp):
#include "Window.h"
Direct3D9::Direct3D9(const Window& _window)
{
HWND windowHandle = *(HWND*)_window.getHandle();
// [...]
pp.hDeviceWindow = windowHandle;
}但是,此代码有效!:
*(HWND*)_window.getHandle() = 0; // changes HWND in WindowData to NULL!有没有一种方法可以在子系统之间传递特定于平台的信息,而不将其暴露在独立的代码中,并保持私有数据的私有性?
编辑当前的WindowData实现
struct Window::WindowData
{
static LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM);
HWND windowHandle;
WNDCLASSEX windowClass;
HINSTANCE processInstance;
};DirectX在表示参数(D3DPRESENT_PARAMETERS::hDeviceWindow)中使用HWND。
发布于 2013-09-08 09:33:51
我会让getHandle (或者更好的getWindowData返回一个WindowData *而不是void * )。然后,让WindowData只是"System/Window.h“文件中的前向声明。
在"Direct3D9“中,使用WindowData的完全定义,因此:
HWND hwnd = _window.getWindowData()->windowHandle;如果在以后的某个阶段,您可以移植到Linux,那么您可以根据实现端的某种WindowData类型的结构,在#ifdef __WIN32/#else内部有一个完全不同的结构。
发布于 2013-09-07 22:37:30
从功能上定义您需要做的事情,然后根据接口实现它。不要公开(公开)指针。然后,根据HWND和特定于平台的API实现接口。
例如:
struct WindowHandleImpl
{
virtual void show() = 0;
virtual void maximize() = 0;
//etc...
};
struct Win32WinHandleImpl : WindowHandleImpl
{
std::unique_ptr<HWND> handle_; //Use deleter...
virtual void show(); //In terms of HWND, using Win32 API
virtual void maximize();
};
struct XWinHandleImpl : WindowHandleImpl
{
//In terms of platform specific handle.
};
struct Window
{
void show(); //In terms of WindowHandleImpl
void maximize();//In terms of WindowHandleImpl
private:
std::unique_ptr<WindowHandleImpl> pimpl_;
};
Window::Window( const Factory& factory )
: pimpl_( factory.createWindow() )
{
}
//or
Window::Window()
: pimpl_( SystemFactory::instance().createWindow() )
{
}发布于 2013-09-07 21:20:16
您可以复制数据并返回一个unique_ptr。或者,您可以将一个HWND返回为void*,而不是HWND*,因为它只是一个指针,尽管它确实利用了实现。记住,其他人仍然可以通过HWND改变你的窗口,我想你对此无能为力。
https://stackoverflow.com/questions/18677828
复制相似问题