【发布时间】:2021-10-19 08:03:25
【问题描述】:
标题:
CChristianLifeMinistryHtmlView m_pHtmlView = nullptr;
来源:
m_pHtmlView = new CChristianLifeMinistryHtmlView();
尝试将其更改为使用智能指针。我可以这样做(在OnInitDialog 内):
auto m_pHtmlView2 = std::make_unique<CChristianLifeMinistryHtmlView>;
但我不知道如何将智能指针定义为CDialog 类的成员变量。我做不到:std::unique_ptr m_pHtmlView2。
我看到了这个讨论 (Using smart pointers as a class member) 并基于此我在标题中尝试了这个:
//CChristianLifeMinistryHtmlView *m_pHtmlView;
std::unique_ptr<CChristianLifeMinistryHtmlView> m_pHtmlView;
但这不会编译:
6>C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.30.30704\include\memory(3087,1): error C2248: 'CChristianLifeMinistryHtmlView::~CChristianLifeMinistryHtmlView': cannot access protected member declared in class 'CChristianLifeMinistryHtmlView'
6>D:\My Programs\2022\MeetSchedAssist\Meeting Schedule Assistant\ChristianLifeMinistryHtmlView.h(104): message : compiler has generated 'CChristianLifeMinistryHtmlView::~CChristianLifeMinistryHtmlView' here
6>D:\My Programs\2022\MeetSchedAssist\Meeting Schedule Assistant\ChristianLifeMinistryHtmlView.h(22): message : see declaration of 'CChristianLifeMinistryHtmlView'
6>C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.30.30704\include\memory(3085): message : while compiling class template member function 'void std::default_delete<CChristianLifeMinistryHtmlView>::operator ()(_Ty *) noexcept const'
6> with
6> [
6> _Ty=CChristianLifeMinistryHtmlView
6> ]
6>C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.30.30704\include\memory(3195): message : see reference to function template instantiation 'void std::default_delete<CChristianLifeMinistryHtmlView>::operator ()(_Ty *) noexcept const' being compiled
6> with
6> [
6> _Ty=CChristianLifeMinistryHtmlView
6> ]
6>C:\Program Files\Microsoft Visual Studio\2022\Preview\VC\Tools\MSVC\14.30.30704\include\memory(3122): message : see reference to class template instantiation 'std::default_delete<CChristianLifeMinistryHtmlView>' being compiled
6>D:\My Programs\2022\MeetSchedAssist\Meeting Schedule Assistant\AvailableBrothersReportPreview.h(52): message : see reference to class template instantiation 'std::unique_ptr<CChristianLifeMinistryHtmlView,std::default_delete<CChristianLifeMinistryHtmlView>>' being compiled
更新
根据我现在拥有的 cmets 中的建议:
- 标题:
std::unique_ptr<CChristianLifeMinistryHtmlView> m_pHtmlView;
- 来源(
OnInitDialog):
m_pHtmlView = std::make_unique<CChristianLifeMinistryHtmlView>();
if (m_pHtmlView != nullptr)
{
m_pHtmlView->Create(nullptr, nullptr, AFX_WS_DEFAULT_VIEW,
m_rctPreviewHtml, this, 0);
m_pHtmlView->ShowWindow(SW_SHOWNORMAL);
if(CMeetingScheduleAssistantApp::WaitForFileToBeReady(m_strTempHtmlFile))
m_pHtmlView->Navigate2(m_strTempHtmlFile, 0, nullptr);
}
它符合并有效。我的弹出对话框显示并且CHtmlView 派生控件可见。凉爽的。但是当我单击确定关闭对话框时,我得到一个异常:
我们如何解决这个问题?
【问题讨论】:
-
unique_ptr需要访问CChristianLifeMinistryHtmlView的析构函数。该错误消息似乎表明(编译器生成的)析构函数受到保护。要么公开析构函数,要么将unique_ptr<CChristianLifeMinistryHtmlView>设置为friend。后者相当棘手,只能作为最后的手段。 -
@IInspectable 我将析构函数更改为公共。然后编译但
m_pHtmlView说它是空的。然后我在 OID 中尝试:m_pHtmlView = std::unique_ptr<CChristianLifeMinistryHtmlView>();,它仍然是空的。因此,虽然它全部编译,但我没有看到。 -
在类定义中:
std::unique_ptr<CChristianLifeMinistryHtmlView> m_pHtmlView;。在构造函数中:m_pHtmlView = std::make_unique<CChristianLifeMinistryHtmlView>();(注意末尾的一对括号;std::make_unique<CChristianLifeMinistryHtmlView>是需要实际调用的函数)。 -
这看起来像一个双重删除错误。您是否尝试在某个时候手动删除
unique_ptr中保存的指针,例如来自析构函数? -
在代码中没有显示的地方,你有双重破坏。可能不是直接属于
m_pHtmlView,而是属于它所属的类。
标签: visual-c++ mfc smart-pointers