将智能指针定义为class的成员变量
Defining a smart pointer as a member variable of a class
Header:
CChristianLifeMinistryHtmlView m_pHtmlView = nullptr;
来源:
m_pHtmlView = new CChristianLifeMinistryHtmlView();
正在尝试将其更改为使用智能指针。我可以做到这一点(在 OnInitDialog
内):
auto m_pHtmlView2 = std::make_unique<CChristianLifeMinistryHtmlView>;
但是我不知道如何将我的智能指针定义为我的 CDialog
class 的成员变量。我做不到:std::unique_ptr m_pHtmlView2
.
我看到了这个讨论 (Using smart pointers as a class member) 并基于此我在 header:
中尝试了这个
//CChristianLifeMinistryHtmlView *m_pHtmlView;
std::unique_ptr<CChristianLifeMinistryHtmlView> m_pHtmlView;
但是不会编译:
6>C:\Program Files\Microsoft Visual Studio22\Preview\VC\Tools\MSVC.30.30704\include\memory(3087,1): error C2248: 'CChristianLifeMinistryHtmlView::~CChristianLifeMinistryHtmlView': cannot access protected member declared in class 'CChristianLifeMinistryHtmlView'
6>D:\My Programs22\MeetSchedAssist\Meeting Schedule Assistant\ChristianLifeMinistryHtmlView.h(104): message : compiler has generated 'CChristianLifeMinistryHtmlView::~CChristianLifeMinistryHtmlView' here
6>D:\My Programs22\MeetSchedAssist\Meeting Schedule Assistant\ChristianLifeMinistryHtmlView.h(22): message : see declaration of 'CChristianLifeMinistryHtmlView'
6>C:\Program Files\Microsoft Visual Studio22\Preview\VC\Tools\MSVC.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 Studio22\Preview\VC\Tools\MSVC.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 Studio22\Preview\VC\Tools\MSVC.30.30704\include\memory(3122): message : see reference to class template instantiation 'std::default_delete<CChristianLifeMinistryHtmlView>' being compiled
6>D:\My Programs22\MeetSchedAssist\Meeting Schedule Assistant\AvailableBrothersReportPreview.h(52): message : see reference to class template instantiation 'std::unique_ptr<CChristianLifeMinistryHtmlView,std::default_delete<CChristianLifeMinistryHtmlView>>' being compiled
更新
根据评论中的建议,我现在有:
- Header:
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
派生控件可见。凉爽的。但是当我单击“确定”关闭对话框时出现异常:
我们如何解决这个问题?
CHtmlView
是从CFormView
派生出来的->CView
,在CView::PostNcDestroy
和delete this;
中删除了自己,所以内存已经被管理了。
将new
替换为std::make_unique
,并立即调用release()
,因为您不想unique_ptr
再删除它。
//m_pHtmlView = new CChristianLifeMinistryHtmlView();
m_pHtmlView = std::make_unique<CChristianLifeMinistryHtmlView>().release();
如果您在原始代码中编写了 new
和 delete
(这也意味着您至少覆盖了 CMyHtmlView::PostNcDestroy
),那么 unique_ptr
可用于替换两者new
和 delete
.
在这种情况下,您在原始代码中只有 new
。您不希望 unique_ptr
管理 delete
Header:
CChristianLifeMinistryHtmlView m_pHtmlView = nullptr;
来源:
m_pHtmlView = new CChristianLifeMinistryHtmlView();
正在尝试将其更改为使用智能指针。我可以做到这一点(在 OnInitDialog
内):
auto m_pHtmlView2 = std::make_unique<CChristianLifeMinistryHtmlView>;
但是我不知道如何将我的智能指针定义为我的 CDialog
class 的成员变量。我做不到:std::unique_ptr m_pHtmlView2
.
我看到了这个讨论 (Using smart pointers as a class member) 并基于此我在 header:
中尝试了这个//CChristianLifeMinistryHtmlView *m_pHtmlView;
std::unique_ptr<CChristianLifeMinistryHtmlView> m_pHtmlView;
但是不会编译:
6>C:\Program Files\Microsoft Visual Studio22\Preview\VC\Tools\MSVC.30.30704\include\memory(3087,1): error C2248: 'CChristianLifeMinistryHtmlView::~CChristianLifeMinistryHtmlView': cannot access protected member declared in class 'CChristianLifeMinistryHtmlView'
6>D:\My Programs22\MeetSchedAssist\Meeting Schedule Assistant\ChristianLifeMinistryHtmlView.h(104): message : compiler has generated 'CChristianLifeMinistryHtmlView::~CChristianLifeMinistryHtmlView' here
6>D:\My Programs22\MeetSchedAssist\Meeting Schedule Assistant\ChristianLifeMinistryHtmlView.h(22): message : see declaration of 'CChristianLifeMinistryHtmlView'
6>C:\Program Files\Microsoft Visual Studio22\Preview\VC\Tools\MSVC.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 Studio22\Preview\VC\Tools\MSVC.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 Studio22\Preview\VC\Tools\MSVC.30.30704\include\memory(3122): message : see reference to class template instantiation 'std::default_delete<CChristianLifeMinistryHtmlView>' being compiled
6>D:\My Programs22\MeetSchedAssist\Meeting Schedule Assistant\AvailableBrothersReportPreview.h(52): message : see reference to class template instantiation 'std::unique_ptr<CChristianLifeMinistryHtmlView,std::default_delete<CChristianLifeMinistryHtmlView>>' being compiled
更新
根据评论中的建议,我现在有:
- Header:
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
派生控件可见。凉爽的。但是当我单击“确定”关闭对话框时出现异常:
我们如何解决这个问题?
CHtmlView
是从CFormView
派生出来的->CView
,在CView::PostNcDestroy
和delete this;
中删除了自己,所以内存已经被管理了。
将new
替换为std::make_unique
,并立即调用release()
,因为您不想unique_ptr
再删除它。
//m_pHtmlView = new CChristianLifeMinistryHtmlView();
m_pHtmlView = std::make_unique<CChristianLifeMinistryHtmlView>().release();
如果您在原始代码中编写了 new
和 delete
(这也意味着您至少覆盖了 CMyHtmlView::PostNcDestroy
),那么 unique_ptr
可用于替换两者new
和 delete
.
在这种情况下,您在原始代码中只有 new
。您不希望 unique_ptr
管理 delete