c++ - 如何在窗口之间移动 std::unique_ptr 而不会冒内存泄漏的风险?
问题描述
我想在 C++ 中完成这个项目并一劳永逸地完成它:从一个窗口的列表中选择一部电影,然后在另一个窗口中显示电影的详细信息。
我已经在这里找到了Remy Lebeau 的解决方案并找到了他的帖子,因为我意识到了他所做的同样的限制:它将原始指针暴露给内存泄漏。
(请原谅我的编码风格)。
MoviesWindow::MovieSelected( const unsigned int uint__MovieKey )
{ ...
std::unique_ptr<MovieBean> uptr__MovieBean = std::make_unique...
...
uptr__MovieBean->SetMovieTitle( row["MovieTitle"] );
uptr__MovieBean->SetYearReleased( row["YearReleased"] );
...
SendMessage( hwnd__MovieWindow, UWM_SendMovieBean, 0, (LPARAM) uptr__MovieBean->get() );
...
}
幸运的是,我有一个优势SendMessage()
:在消息处理程序返回之前它不会结束(释放std::unique_ptr
),并且消息处理程序的工作是克隆MovieBean
.
MovieWindow::HandleUwmSendMovieBean( const HWND hwnd__MovieWindow, const UINT uint__WindowMessage, const WPARAM wParam, const LPARAM lParam )
{ UPTR__MovieBean = std::move( (*((MovieBean*) lParam).Clone() );
...
}
似乎正确的方法是通过发送对处理程序的引用并在引用上使用,将std::unique_ptr
with的所有权保留到实际传输时刻。MovieSelected()
std::move
MoviesWindow::MovieSelected( const unsigned int uint__MovieKey )
{ ...
SendMessage( hwnd__MovieWindow, UWM_SendMovieBean, 0, (LPARAM) &uptr__MovieBean );
...
}
但我无法弄清楚如何将参考lParam
从std::move
. 这似乎是一个,但不是。
MovieWindow::HandleUwmSendMovieBean( const HWND hwnd__MovieWindow, const UINT uint__WindowMessage, const WPARAM wParam, const LPARAM lParam )
{ UPTR__NewMovieBean = std::move( reinterpret_cast<std::unique_ptr<MovieBean>*>( lParam ) );
...
}
我已经尝试了所有我能想到的组合,并确保发送的地址是接收并提供给 std::move 的地址。我得到的只是不断的编译器错误(包括一个现在非常讨厌的 about std::remove_reference
)和崩溃。任何见解将不胜感激。
解决方案
SendMessage
并且unique_ptr
绝对不是为彼此而生的。我可以在这里给出很多提示,但最好的办法是不要通过 HWND 消息走私智能指针。
我不知道 a 是什么UWM_SendMovieBean
,但我猜这是您基于 offWM_USER
或RegisterWindowsMessage
. 因此,您真正在做的事情听起来像是在尝试使用 SendMessage 向另一个代码组件发出信号,而不是两个窗口的支持类之间的正式合同。这样做并不是最糟糕的事情,但是对于像 unique_ptr 这样专门的类,它变得更加难以实现。
便宜又容易做的事情是让两个窗口共享row
您拥有的数据结构。然后您的发送消息只是将uint__MovieKey
作为您的自定义消息的 WPARAM 或 LPARAM 发送。
但是,如果您在我的团队中,并且我们正在一起构建这个应用程序,我会为您提供 Model-View-Presenter(和其他 MVC 设计)的速成课程,使这些类型的功能设计更易于维护。
推荐阅读
- wp-cli - WordPress CLI 错误:可调用的“Queue_Command”不存在,不能注册为`wp queue`
- sql - 创建 Oracle SQL 触发器错误
- swift - 在 appDelegate 中设置 UITabBarItem 徽章值
- angular - Angular 4中的多个数据发布到服务器
- configuration - 项目中的 CMake 依赖项
- excel - VBA通过Excel中的循环从找到的列中收集信息
- excel - 需要从 Excel 表中删除空行,然后调整表的大小 - 使用 VBA
- sas - 为 SAS 变量添加标签
- python - pandas2ri.ri2py_dataframe(r_dataframe) 返回浮点数而不是 ISO-8601 (YYYY-MM-DD) 格式的日期
- scons - Scons 使用 Clang -MJ 选项