8

我在使用静态地图作为 C++ 成员时遇到问题。我的头文件是:

class Article
{
public:
//
static map<string,Article*> dictionary;
....
....   
};

在我的构造函数中,我首先调用以下方法:

 void Article::InitializeDictionary()
 {
   #ifndef DICT
   #define DICT
   map<string,Article*> Article::dictionary;
   #endif
 }

基于有关此的其他帖子,我应该声明静态成员,但是当我尝试这样做时,出现以下错误:

Error   1   error C2655: 'Article::dictionary' : definition or redeclaration illegal in current scope   c:\.......\article.cpp  88  1

如果我将功能更改为以下内容:

void Article::InitializeDictionary()
{
    #ifndef DICT
    #define DICT
    Article::dictionary["null"] = 0;
    #endif
}

我收到此错误:

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)

关于我能做什么的任何想法?

4

2 回答 2

13

您必须正确声明和定义静态成员(在方法中这样做是错误的):

class Article
{
public:
//
static map<string,Article*> dictionary;
....
....   
};

map<string,Article*> Article::dictionary;

int main() {
    //..
}

你在评论中问过:

我尝试在类声明之后执行此操作,但出现错误,但如果我在函数定义所在的 .cpp 文件中执行此操作,则它可以工作。这是为什么?

由于静态成员在类的所有实例之间共享,因此它们必须在一个且仅一个编译单元(位置)中定义。实际上,它们是具有一些访问限制的全局变量。

如果您尝试在标头中定义它们,它们将在包含该标头的每个模块中定义,并且您会在链接过程中遇到错误,因为它会找到所有重复的定义。

于 2013-10-12T16:03:54.433 回答
6

您在课堂上声明 static 没有任何问题。

但是,您需要告诉编译器为静态成员保留存储空间:您需要定义它。为此,请包括该行

map<string,Article*> Article::dictionary;

仅在一个编译单元中并在全局范围内;即不在方法或命名空间中。

正常的做法是将该行放在与您的类关联的文件中。Article如果您将该行放在头文件中,那么多个编译单元可以定义它,这会给您带来链接错误。即使使用包含警卫也会发生这种情况。

重要的是要注意,map将在程序的main函数运行之前进行初始化。

于 2013-10-12T16:07:11.953 回答