看来我试图用不可复制的对象填充std :: map,但我还没有实现 .

General problem

我想使用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'

我不确定这是正确的解释,但似乎“图像”缺乏函数“插入”中使用的公共方法 . (复制操作符?复制构造函数?) .

What I have tried

我试图在 Map 中使用引用,但似乎在容器中放置引用永远不会起作用 . 我试图使用原始指针,但是当我试图删除析构函数中的所有图像时,我遇到了错误 . 我发生了this other (and quite similar) question,我开始关心聪明的指针 . 所以现在,我正在按照答案中的建议尝试使用std :: shared_ptr . 但是,我的情况略有不同 .

我想写一个返回图像的函数“find” . 如果键(其路径)存在,“find”给出在 Map 中找到的图像,否则它加载图像,将其添加到 Map 并返回它 . 所以我不能在括号内创建一个新图像,因为我需要指针 .

我想出的唯一可以编译的版本是:

(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

有人知道我错在哪里,或者是否有更简单或更好的解决方案?