关于c ++:从另一个类访问静态成员函数


Accessing a static member function from another class

我在C++类中有一个静态STL映射,并有另一个静态成员函数来返回映射中对象的常量指针。该映射对于类中的所有对象都是通用的。

唯一的问题是,我需要搜索这个映射并从另一个类中设置它,这个类在另一个.cpp/.h文件中,当我尝试在VS2010中编译它们时,会得到未解析的外部符号。方法在Timestream类中定义为

1
2
static void setRoomList(std::map<std::string, RoomDescription> rl);
static RoomDescription * getRoom(std::string ref);

这两个功能都是公共的,因此不应该存在访问问题。这些函数在timestream.cpp文件中定义为普通函数,即,

1
2
3
4
5
6
7
8
9
RoomDescription * Timestream::getRoom(std::string ref)
{
    std::map<std::string, RoomDescription>::iterator cIter= roomList.find(ref);

    if(cIter!=roomList.end())
        return &(cIter->second);

    return NULL;
}

我想把这个叫做

1
RoomDescription *r =Timestream::getRoom("Bathroom")

来自另一个班级。网络上的其他帖子似乎在谈论使用extern,但我不确定。我不明白为什么这和从不同的类调用其他成员函数有什么不同?

谢谢,詹姆斯

编辑:是的,我已经宣布

1
std::map<std::string, RoomDescription> roomList;

在timestream.cpp文件的顶部。在标题中,它被定义为

1
static  std::map<std::string, RoomDescription> roomList;

我已经将roomDescription的头包含在我要从中调用这些方法的类的头中。

我得到的错误是

Import.obj : error LNK2019: unresolved external symbol"public: static void __cdecl Timestream::setRoomList(class std::map,class std::allocator >,class RoomDescription,struct std::less,class std::allocator > >,class std::allocator,class std::allocator > const ,class RoomDescription> > >)" (?setRoomList@Timestream@@SAXV?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@VRoomDescription@@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@@VRoomDescription@@@std@@@2@@std@@@Z) referenced in function"public: int __thiscall Import::getRoomData(void)" (?getRoomData@Import@@QAEHXZ)

Timestream.obj : error LNK2001: unresolved external symbol"private: static class std::map,class std::allocator >,class RoomDescription,struct std::less,class std::allocator > >,class std::allocator,class std::allocator > const ,class RoomDescription> > > Timestream::roomList" (?roomList@Timestream@@0V?$map@V?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@std@@VRoomDescription@@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@@VRoomDescription@@@std@@@2@@std@@A)


您需要添加:

1
std::map<std::string, RoomDescription> Timestream::roomList;

Timestream.cpp,或调用实现文件的任何对象。

这将定义静态成员。在头文件中,您只声明它。


我猜想未解析的外部符号是roomList;这是错误消息中包含的一个重要信息。而且,据推测,roomList是类定义中声明的静态成员。如果这些假设是正确的,那么错误的原因是代码没有roomList的定义。

通常,静态成员必须在类定义中声明并在源文件中定义:

1
2
3
4
5
6
7
// foo.h:
class C {
    static int data;
};

// foo.cpp:
int C::data = 42;

这与从另一个类访问静态成员无关。如果您试图从声明它的类中访问它,则会得到相同的错误。

编辑:在新发布的错误消息中,缺少两个名称:setRoomListroomList。请注意,roomListTimestream的成员,必须这样定义,即它的定义必须包括Timestream::。如上所示,它只是一个全局数据对象,而不是Timestream的成员。setRoomList的问题可能是相同的。