我在使用静态地图作为C++成员时遇到了麻烦.我的头文件是:
class Article
{
public:
//
static map<string,Article*> dictionary;
....
....
};
Run Code Online (Sandbox Code Playgroud)
在我的构造函数中,我首先调用以下方法:
void Article::InitializeDictionary()
{
#ifndef DICT
#define DICT
map<string,Article*> Article::dictionary;
#endif
}
Run Code Online (Sandbox Code Playgroud)
基于关于此的其他帖子我应该声明静态成员但是当我尝试这样做时,我收到以下错误:
Error 1 error C2655: 'Article::dictionary' : definition or redeclaration illegal in current scope c:\.......\article.cpp 88 1
Run Code Online (Sandbox Code Playgroud)
如果我将功能更改为以下内容:
void Article::InitializeDictionary()
{
#ifndef DICT
#define DICT
Article::dictionary["null"] = 0;
#endif
}
Run Code Online (Sandbox Code Playgroud)
我收到此错误:
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)
Run Code Online (Sandbox Code Playgroud)
关于我能做什么的任何想法?
4pi*_*ie0 11
你必须正确声明和定义静态成员(在方法中这样做是错误的):
class Article
{
public:
//
static map<string,Article*> dictionary;
....
....
};
map<string,Article*> Article::dictionary;
int main() {
//..
}
Run Code Online (Sandbox Code Playgroud)
你在评论中提到:
我尝试在类声明后执行此操作并出现错误但是如果我在.cpp文件中执行此操作,其中函数定义是有效的.这是为什么?
由于静态成员在类的所有实例之间共享,因此必须在一个且仅一个编译单元(位置)中定义它们.实际上,它们是具有一些访问限制的全局变量.
如果您尝试在标题中定义它们,它们将在包含该标题的每个模块中定义,并且在链接期间您将发现错误,因为它会找到所有重复的定义.
您在班级中声明静态没有任何问题.
但是,您需要告诉编译器为静态成员保留存储:您需要定义它.要做到这一点,包括线
map<string,Article*> Article::dictionary;
Run Code Online (Sandbox Code Playgroud)
在一个编制单元和全球范围内; 即不在方法或命名空间中.
通常要做的是将该行放在与您的类关联的源文件中Article.如果将行放在头文件中,则多个编译单元可以定义它,这将给出链接错误.即使使用包含警卫也会发生这种情况.
重要的是要注意,map将在程序的main函数运行之前进行初始化.