我有几个与此代码有关的问题,但我会单独问他们。
我熟悉智能指针的概念,因为我之前使用过不同的库(如Teigha for DGN)。但是,最近我在StackOverflow上发了一条评论,我认为我应该考虑使用unique_ptr
代替new
和delete
。
我一直在处理我自己的代码,将菜单项位图添加到我的程序中,并且进展顺利。我认为这对于独特的指针来说是一个很好的选择。
我有一张地图:
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
}
}
工作正常:
我不会忘记内存泄漏因为我了解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 *
对象的正确方法。所以我不明白并发症的失败。
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
语句。