将智能指针定义为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

更新

根据评论中的建议,我现在有:

std::unique_ptr<CChristianLifeMinistryHtmlView> m_pHtmlView;


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::PostNcDestroydelete this;中删除了自己,所以内存已经被管理了。

new替换为std::make_unique,并立即调用release(),因为您不想unique_ptr再删除它。

//m_pHtmlView = new CChristianLifeMinistryHtmlView();
m_pHtmlView = std::make_unique<CChristianLifeMinistryHtmlView>().release();

如果您在原始代码中编写了 newdelete(这也意味着您至少覆盖了 CMyHtmlView::PostNcDestroy),那么 unique_ptr 可用于替换两者newdelete.

在这种情况下,您在原始代码中只有 new。您不希望 unique_ptr 管理 delete