I'm having trouble using a static map as a C++ member. My header file is:
class Article
{
public:
//
static map<string,Article*> dictionary;
....
....
};
In my constructor I call the following method first:
void Article::InitializeDictionary()
{
#ifndef DICT
#define DICT
map<string,Article*> Article::dictionary;
#endif
}
Based on other posts about this I am supposed to declare the static member but when I try to do this I get the following error:
Error 1 error C2655: 'Article::dictionary' : definition or redeclaration illegal in current scope c:\.......\article.cpp 88 1
If I change the function to the following:
void Article::InitializeDictionary()
{
#ifndef DICT
#define DICT
Article::dictionary["null"] = 0;
#endif
}
I get this error:
Error 1 error LNK2001: unresolved external symbol "public: static class std::map<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class Article *,struct std::less<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > >,class std::allocator<struct std::pair<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const ,class Article *> > > Article::dictionary" (?dictionary@Article@@2V?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@PAVArticle@@U?$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@@PAVArticle@@@std@@@2@@std@@A)
Any ideas on what I can do?
You have to properly declare and define static member (doing this in method is wrong):
class Article
{
public:
//
static map<string,Article*> dictionary;
....
....
};
map<string,Article*> Article::dictionary;
int main() {
//..
}
You've asked in the comment:
I tried doing this after the class declaration and got an error but if I do this in the .cpp file where the function definitions are it works. Why is that?
Since static members are shared between ALL instances of a class, they have to be defined in one and only one compilation unit (place). Really, they're global variables with some access restrictions.
If you try to define them in the header, they will be defined in every module that includes that header, and you'll get errors during linking as it finds all of the duplicate definitions.
There's nothing wrong with your declaration of the static in your class.
However, you need to tell the compiler to reserve storage for the static member: you need to define it. To do this include the line
map<string,Article*> Article::dictionary;
in exactly one compilation unit and at global scope; i.e. not in a method or a namespace.
The normal thing to do is to put that line in the source file associated with your Article
class. If you put the line in a header file then multiple compilation units could define it which will give you link errors. This will happen even with include guards.
It's important to note that the initialisation of the map
will occur before the program's main
function is run.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With