views:

83

answers:

3

Hello,

I've been spoilt with c# coding the last few years and now I'm back onto c++ and finding that I'm having trouble with stuff that is supposed to be simple. I'm using a third party library for gamedev called DarkGDK (any commands which are prefixed with db), however DGDK isn't the problem.

Heres my code:

System.h

#pragma once

#include <string>
#include <map>
#include "DarkGDK.h"

using namespace std;

class System
{
public:
    System();
    ~System();
    void Initialize();

    static void LoadImage(string fileName, string id);
    static int GetImage(string id);

private:
    map<string, int> m_images;
};

System.cpp

#include "System.h"

System::System()
{
}

System::~System()
{
}

void System::Initialize()
{
    dbSetDisplayMode (1024, 640, 32);
    dbSetWindowTitle ("the Laboratory");
    dbSetWindowPosition(100, 10);

    dbSyncOn         ();
    dbSyncRate       (60);

    dbRandomize(dbTimer());
}

void System::LoadImage(string fileName, string id)
{
    int i = 1;

    while (dbImageExist(i))
    {
        i++;
    }

    dbLoadImage(const_cast<char*>(fileName.c_str()), i, 1);
    m_images[id] = i;
}

int System::GetImage(string id)
{
    return m_images[id];
}

The idea here is to have a map which maps strings against integer values, to access images with a string instead of hardcoded values. This class isn't done, so it doesn't handle anything like unloading images. I want to access the image methods without passing an instance of System, so I used static.

Now i get this error:

blahblah\system.cpp(39) : error C2677: binary '[' : no global operator found which takes type 'std::string' (or there is no acceptable conversion)

If I change the map to static, I get this linker error:

1>System.obj : error LNK2001: unresolved external symbol "private: static class std::map,class std::allocator >,int,struct std::less,class std::allocator > >,class std::allocator,class std::allocator > const ,int> > > System::m_images" (?m_images@System@@0V?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@HU?$less@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@H@std@@@2@@std@@A)

Can any of you bright chaps help me out?

cheers, Draknir

+6  A: 

The first one is a compiler error as you can not access the non-static data members from a static method. this pointer is not implictly passed to static methods hence they can not access data members bound to an instance.

In the seconds case, note that static map<string,int> m_images; is just a declaration of a variable. You need to define the static member variable using map<string, int> System::m_images; in the source file. This will get rid of the linker error.

Naveen
Thanks for your answer Naveen, I did indeed realize that the map should be static (not sure why I included that error in my question). The linker error is what got me, defining it in the cpp fixed it right up. Cheers!
Draknir
+1  A: 

Since m_images is a non-static member of the class, when you access it from a static member function, you need to specify the object whose m_images member you want to use. If there's only supposed to be a single m_images object shared by all objects of that class, you want to make it static as well.

Jerry Coffin
+1  A: 

Static members are always explicitly defined in your program. So it has to be somehow initialised inside System.cpp. If not you get the unresolved external error.

Here's a link to a couple of examples

http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.10

Slartibartfast
Thanks for the link, it was helpful :)
Draknir
You're welcome :)
Slartibartfast