Resource management with std::map?

Hello, everyone.

I'm currently building a simple image manager which works with std::map internaly. It's supposed to work similarly to a repository: Images are loaded, placed in a map with their filepath for key and later accessed via this same key.
I've designed a symbolic representation of what the real class would look like using dummy classes as a test:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//The extremely heavy resource
class X
{
    public:
        static unsigned int XConstructCalls;

        X() { printf("X::X()\n"); ++XConstructCalls; }
        X(const X& other) { printf("X::X(const X&)\n"); ++XConstructCalls; }
        ~X() { printf("X::~X()\n"); }        
};

unsigned int X::XConstructCalls = 0;

//The Manager
class XManager
{
    public:
        XManager() { printf("XManager::XManager()\n"); }
        ~XManager() { printf("XManager::~XManager()\n"); }

        X& GetX(const std::string& XName);

    private:

        X m_TempX;
        X m_DefaultX; //To be used when resource loading fails
        std::map<std::string, X> m_XMap;
        std::map<std::string, X>::iterator m_MapIterator;
};

X& XManager::GetX(const std::string& XName)
{
    m_MapIterator = m_XMap.find(XName);

    if(m_MapIterator != m_XMap.end())
    {
        return m_MapIterator->second;
    }

    m_MapIterator = m_XMap.insert(std::pair<std::string, X>(XName, m_TempX)).first;

    return m_MapIterator->second;
};


I ran this piece of code:
1
2
3
4
5
6
7
8
int main()
{
    XManager xman;
    xman.GetX("X1");
    
    printf("%d\n", X::XConstructCalls);
    return 0;
}


And I got a whooping 5 constructor calls from X.
Two standard from the XManager class, that's OK, But there are three from copy constructing. That's pretty expensive considering Images are heavy resources. Where do these calls come from? Is there anything I can do to make this more efficient? Any completely different solutions are gladly appretiated too!

Thanks in advance and Best Regards,
Deimos
Use pointers to objects instead of objects as the map values.
You have m_TempX and m_DefaultX in XManager, that's 2.

You probably copy one into the std::pair and one out again before actually doing the insert, that's another 2.

http://www.cplusplus.com/forum/general/13779/
Thanks, helios and kbw!
I think I'll go with dynamic memory allocation for this one, something like this:
1
2
3
4
5
6
7
8
9
10
11
12
13
X& XManager::GetX(const std::string& XName)
{
    m_MapIterator = m_XMap.find(XName);

    if(m_MapIterator != m_XMap.end())
    {
        return *m_MapIterator->second;
    }

    m_MapIterator = m_XMap.insert(std::pair<std::string, X*>(XName, new X(m_TempX))).first;

    return *m_MapIterator->second;
};


Thanks for your help! :)
Topic archived. No new replies allowed.