在VS2017中使用unique_ptr <cbitmap>

时间:2018-04-17 09:01:42

标签: unique-ptr

我有几个与此代码有关的问题,但我会单独问他们。

我熟悉智能指针的概念,因为我之前使用过不同的库(如Teigha for DGN)。但是,最近我在StackOverflow上发了一条评论,我认为我应该考虑使用unique_ptr代替newdelete

我一直在处理我自己的代码,将菜单项位图添加到我的程序中,并且进展顺利。我认为这对于独特的指针来说是一个很好的选择。

我有一张地图:

using MenuBitmapsMap = map<UINT, CBitmap*>;

我已经宣布这是我班上的一个变量。然后我多次调用此方法来构建地图并更新我的菜单:

void CChristianLifeMinistryEditorDlg::UpdateMenuBitmap(CMenu *pMenu, UINT uCommandID, UINT uBMPResource, bool bDisabled /*false*/)
{
    CBitmap *pBitmap = new CBitmap;                       // Create a new CBitmap pointer
    if (pBitmap == nullptr)
        return;

    if (pBitmap->LoadBitmap(uBMPResource) == NULL)        // Load the image from the resources
    {
        delete pBitmap;
        return;
    }

    theApp.SetBitmapBackgroundAsMenuColour(*pBitmap);        // Update the image background
    m_mapMenuBitmap.emplace(uCommandID, pBitmap);            // Add the menu / bitmap pair to the map

    if (!pMenu->SetMenuItemBitmaps(uCommandID, MF_BYCOMMAND, // Update the menu bitmaps
        m_mapMenuBitmap.at(uCommandID),
        m_mapMenuBitmap.at(uCommandID)))
    {
        // #UpdateMenuBitmap Failed to set the menu item bitmaps
    }
}

工作正常:

Menu

我不会忘记内存泄漏因为我了解map取得CBitmap*的所有权并自行删除。

但我试图使用:

unique_ptr<CBitmap> pBitmap = make_unique<CBitmap>;

我添加了#include <memory>但是我收到了这个错误:

  

没有合适的构造函数可以从“”转换为“std :: unique_ptr&gt;”

更新

我将地图更改为:

using MenuBitmapsMap = map<UINT, unique_ptr<CBitmap>>;

在我的职能中:

unique_ptr<CBitmap> pBitmap = make_unique<CBitmap>();

现在全部编译。但现在我不能这样做:

if (!pMenu->SetMenuItemBitmaps(uCommandID, MF_BYCOMMAND, // Update the menu bitmaps
    m_mapMenuBitmap.at(uCommandID),
    m_mapMenuBitmap.at(uCommandID)))
{
    // #UpdateMenuBitmap Failed to set the menu item bitmaps
}
  

no suitable conversion function from "std::unique_ptr<CBitmap, std::default_delete<CBitmap>>" to "const CBitmap *" exists

SetMenuItemBitmaps需要CBitmap *个参数。在我看来,CBitmap*并使用new更容易。

混淆。

更新

如果我改变这一点:

if (!pMenu->SetMenuItemBitmaps(uCommandID,
    bByPosition ? MF_BYPOSITION : MF_BYCOMMAND,      // Update the menu bitmaps
    m_mapMenuBitmap.at(uCommandID).get(),
    m_mapMenuBitmap.at(uCommandID).get()))
{
    // #UpdateMenuBitmap Failed to set the menu item bitmaps
}

...所以现在它使用get()方法我得到更多的编译器错误:

4>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\xmemory0(919): error C2661: 'std::pair<const _Kty,_Ty>::pair': no overloaded function takes 2 arguments
4>        with
4>        [
4>            _Kty=UINT,
4>            _Ty=std::unique_ptr<CBitmap,std::default_delete<CBitmap>>
4>        ]
4>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\xtree(774): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,UINT&,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>&>(_Alloc &,_Objty *const ,UINT &,std::unique_ptr<CBitmap,std::default_delete<CBitmap>> &)' being compiled
4>        with
4>        [
4>            _Alloc=std::allocator<std::_Tree_node<std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>,std::_Default_allocator_traits<std::allocator<std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>>>::void_pointer>>,
4>            _Ty=std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>,
4>            _Objty=std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>
4>        ]
4>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\xtree(773): note: see reference to function template instantiation 'void std::_Default_allocator_traits<_Alloc>::construct<_Ty,UINT&,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>&>(_Alloc &,_Objty *const ,UINT &,std::unique_ptr<CBitmap,std::default_delete<CBitmap>> &)' being compiled
4>        with
4>        [
4>            _Alloc=std::allocator<std::_Tree_node<std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>,std::_Default_allocator_traits<std::allocator<std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>>>::void_pointer>>,
4>            _Ty=std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>,
4>            _Objty=std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>
4>        ]
4>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\xtree(961): note: see reference to function template instantiation 'std::_Tree_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_Tree_comp_alloc<_Traits>::_Buynode<UINT&,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>&>(UINT &,std::unique_ptr<CBitmap,std::default_delete<CBitmap>> &)' being compiled
4>        with
4>        [
4>            _Ty=std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>,
4>            _Alloc=std::allocator<std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>>,
4>            _Traits=std::_Tmap_traits<UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>,std::less<UINT>,std::allocator<std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>>,false>
4>        ]
4>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.13.26128\include\xtree(961): note: see reference to function template instantiation 'std::_Tree_node<_Ty,std::_Default_allocator_traits<_Alloc>::void_pointer> *std::_Tree_comp_alloc<_Traits>::_Buynode<UINT&,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>&>(UINT &,std::unique_ptr<CBitmap,std::default_delete<CBitmap>> &)' being compiled
4>        with
4>        [
4>            _Ty=std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>,
4>            _Alloc=std::allocator<std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>>,
4>            _Traits=std::_Tmap_traits<UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>,std::less<UINT>,std::allocator<std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>>,false>
4>        ]
4>d:\my programs\2017\meetschedassist\meeting schedule assistant\christianlifeministryeditordlg.cpp(6204): note: see reference to function template instantiation 'std::pair<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<_Ty>>>,bool> std::_Tree<std::_Tmap_traits<_Kty,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>,_Pr,_Alloc,false>>::emplace<UINT&,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>&>(UINT &,std::unique_ptr<CBitmap,std::default_delete<CBitmap>> &)' being compiled
4>        with
4>        [
4>            _Ty=std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>,
4>            _Kty=UINT,
4>            _Pr=std::less<UINT>,
4>            _Alloc=std::allocator<std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>>
4>        ]
4>d:\my programs\2017\meetschedassist\meeting schedule assistant\christianlifeministryeditordlg.cpp(6204): note: see reference to function template instantiation 'std::pair<std::_Tree_iterator<std::_Tree_val<std::_Tree_simple_types<_Ty>>>,bool> std::_Tree<std::_Tmap_traits<_Kty,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>,_Pr,_Alloc,false>>::emplace<UINT&,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>&>(UINT &,std::unique_ptr<CBitmap,std::default_delete<CBitmap>> &)' being compiled
4>        with
4>        [
4>            _Ty=std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>,
4>            _Kty=UINT,
4>            _Pr=std::less<UINT>,
4>            _Alloc=std::allocator<std::pair<const UINT,std::unique_ptr<CBitmap,std::default_delete<CBitmap>>>>
4>        ]

这一切都归结为我想:

  

std::pair<const _Kty,_Ty>::pair': no overloaded function takes 2 arguments

我不明白。

更新

我看到了这个question,这意味着使用get()是传递CBitmap *对象的正确方法。所以我不明白并发症的失败。

As Requested

void CChristianLifeMinistryEditorDlg::UpdateMenuBitmap(CMenu *pMenu, UINT uCommandID, UINT uBMPResource, 
                                                       bool bByPosition /*false*/, bool bDisabled /*false*/)
{
    if (pMenu == nullptr)
        return;

    // See if the bitmap already exists. If it does, then delete it.
    // This will happen when we are changing the image state to/from grayscale.
    if (m_mapMenuBitmap.count(uCommandID) > 0)
        m_mapMenuBitmap.erase(uCommandID);

    unique_ptr<CBitmap> pBitmap = make_unique<CBitmap>();
    //CBitmap *pBitmap = new CBitmap;
    if (pBitmap == nullptr)
        return;

    if (pBitmap->LoadBitmap(uBMPResource) == NULL)
    {
        //delete pBitmap;
        return;
    }

    theApp.SetBitmapBackgroundAsMenuColour(*pBitmap);

    if (bDisabled)
        theApp.SetBitmapAsGrayScale(*pBitmap);

    m_mapMenuBitmap.emplace(uCommandID, pBitmap);

    if (!pMenu->SetMenuItemBitmaps(uCommandID,
                    bByPosition ? MF_BYPOSITION : MF_BYCOMMAND, 
                    m_mapMenuBitmap.at(uCommandID).get(),
                    m_mapMenuBitmap.at(uCommandID).get()))
    {
        // #UpdateMenuBitmap Failed to set the menu item bitmaps
    }
}

第6204行是函数中的第一个if语句。

0 个答案:

没有答案