首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++从不透明指针传输私有数据

C++从不透明指针传输私有数据
EN

Stack Overflow用户
提问于 2013-09-07 20:54:48
回答 3查看 644关注 0票数 1

最近,我了解了C++中的不透明指针。我已经开始使用它们来隐藏特定于平台的私有成员。例如引用<windows.h>中的定义等。

现在,我有几个相互建立起来的系统,需要相互交流。例如,Direct3D需要一个窗口句柄(HWND)。我不想向我的核心系统公开平台定义,但是我的子系统需要通信这些数据。

我正在公开不透明的数据,并允许通过一个空指针访问。这允许访问所有私有数据。

示例用法(main.cpp):

代码语言:javascript
复制
// System:: namespace is my platform specific code
System::Window window;
System::DirectX::Direct3D9 gfxcontext(window);

窗口定义(System/Window.h):

代码语言:javascript
复制
class Window
{
    WindowData* data; // Opaque pointer
public:
    void* getHandle() const; // returns an HWND handle
    Window();
    ~Window();
}

如何检索有用的数据(Direct3D9.cpp):

代码语言:javascript
复制
#include "Window.h"

Direct3D9::Direct3D9(const Window& _window)
{
    HWND windowHandle = *(HWND*)_window.getHandle();
    // [...]
    pp.hDeviceWindow = windowHandle;
}

但是,此代码有效!:

代码语言:javascript
复制
*(HWND*)_window.getHandle() = 0; // changes HWND in WindowData to NULL!

有没有一种方法可以在子系统之间传递特定于平台的信息,而不将其暴露在独立的代码中,并保持私有数据的私有性?

编辑当前的WindowData实现

代码语言:javascript
复制
struct Window::WindowData
{
    static LRESULT CALLBACK MessageHandler(HWND, UINT, WPARAM, LPARAM);
    HWND windowHandle;
    WNDCLASSEX windowClass;
    HINSTANCE processInstance;
};

DirectX在表示参数(D3DPRESENT_PARAMETERS::hDeviceWindow)中使用HWND。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-09-08 09:33:51

我会让getHandle (或者更好的getWindowData返回一个WindowData *而不是void * )。然后,让WindowData只是"System/Window.h“文件中的前向声明。

在"Direct3D9“中,使用WindowData的完全定义,因此:

代码语言:javascript
复制
HWND hwnd = _window.getWindowData()->windowHandle;

如果在以后的某个阶段,您可以移植到Linux,那么您可以根据实现端的某种WindowData类型的结构,在#ifdef __WIN32/#else内部有一个完全不同的结构。

票数 1
EN

Stack Overflow用户

发布于 2013-09-07 22:37:30

从功能上定义您需要做的事情,然后根据接口实现它。不要公开(公开)指针。然后,根据HWND和特定于平台的API实现接口。

例如:

代码语言:javascript
复制
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() )
{
}
票数 1
EN

Stack Overflow用户

发布于 2013-09-07 21:20:16

您可以复制数据并返回一个unique_ptr。或者,您可以将一个HWND返回为void*,而不是HWND*,因为它只是一个指针,尽管它确实利用了实现。记住,其他人仍然可以通过HWND改变你的窗口,我想你对此无能为力。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/18677828

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档