似乎我正在尝试使用不可复制的对象填充std :: map,但我还没有实现。
一般问题
我想使用std :: map来存储一些名为Image的类型的对象(更准确地说,它是Gdiplus :: Image)。我不能写像:
map<string, Gdiplus::Image> loadedImages ;
Gdiplus::Image newImage( CString("totoro.png") );
loadedImages.insert(std::pair<string, Gdiplus::Image>( "totoro", newImage ) );
功能“插入”似乎是这里的问题。编译器说:
'Gdiplus::Image::Image' : cannot access private member declared in class 'Gdiplus::Image'
我不确定这是正确的解释,但似乎“Image”缺少函数“insert”中使用的公共方法。 (复制操作符?复制构造函数?)。
我尝试了什么
我试图在地图中使用引用,但似乎在容器中放置引用永远不会起作用。我试图使用原始指针,但是当我试图删除析构函数中的所有图像时,我遇到了错误。我遇到了this other (and quite similar) question,我开始关心聪明的指针。所以现在,我正在按照答案中的建议尝试使用std :: shared_ptr。但是,我的情况略有不同。
我想编写一个返回图像的函数“find”。如果键(其路径)存在,“find”给出在地图中找到的图像,否则它加载图像,将其添加到地图并返回它。所以我不能在括号内创建一个新图像,因为我需要指针。
我想出的唯一可以编译的版本是:
(Drawer.h)
#include <map>
#include <memory>
#include <Gdiplus.h>
using std::map ;
using std::shared_ptr ;
class CDrawer
{
public:
CDrawer(void);
~CDrawer(void);
void drawImage(string p_pathToPicture)
private:
map<string, shared_ptr<Gdiplus::Image>> m_loadedImages ; // Keep every image in memory instead of loading them each time. Each image has its path as a key.
Gdiplus::Image* findImage(string& p_path); // get the image from the map if the image is already loaded, else load it.
};
(Drawer.cpp)(构造函数和析构函数为空)
void CDrawer::drawImage(string p_pathToImage)
{
// get the bounding rectangle of the image
//...
Gdiplus::Image* l_image = findImage(p_pathToImage);
// Draw the image.
//...
}
Gdiplus::Image* CDrawer::findImage(string& p_pathToImage)
{
auto iterator = m_loadedImages.find(p_pathToImage);
if (iterator == m_loadedImages.end() ) // image not found, so we have not already loaded it
{
shared_ptr<Gdiplus::Image> l_newImage( new Gdiplus::Image( CString( p_pathToImage.c_str()) ) ); // Load the image (I know I have to add error code)
m_loadedImages.insert( std::pair<string, shared_ptr<Gdiplus::Image>>( p_pathToImage, l_newImage ) ); // Add the image to the list
return l_newImage.get() ;
}
else return iterator->second.get() ; // image found, so it is already loaded and we provide the existing one.
}
但是在运行时,当调用Drawer的析构函数时,它会产生以下错误:
Unhandled exception at 0x00C18CEE in MyProgramm.exe: 0xC0000005: Access violation reading location 0x02F36D78
有人知道我错在哪里,或者是否有更简单或更好的解决方案?