2017-04-18 146 views
0

我在我的API中随机生成sessionId。对于一个sessionId,我需要同时将userId(对sessionId所属的用户)和用户类型(例如,管理员,所有者等)进行保存。C++类映射对象

这是我的HashMap:

std::map<std::string, SessionData*> sessionMap; 

这是我SessionData类:

class SessionData 
{ 
public: 
    SessionData(std::string pUserId, std::string pUserType) 
    { 
     userId = pUserId; 
     userType = pUserType; 
    } 

    ~SessionData() 
    { 
    } 

    std::string userId; 
    std::string userType; 
}; 

现在我不觉得我的问题的任何解决方案。如何在地图上保存sessionIduserIduserType?我有char sessionId[80]已经有我的算法生成sessionId(算法对于这种情况并不重要)。我在C++新的,但我认为这是类似的东西:

sessionMap[sessionId].insert(); 

但我不知道如何插入userIduserType,因为我的地图是关键< - >对象。关键是sessionId和对象是我的类SessionDatauserIduserType

编辑1:

我typedef结构映射:在地图

typedef std::map<std::string, SessionData*> sessionMap_map_t; 
sessionMap_map_t sessionMap; 

新的插入数据(当前时间):

sessionMap.insert(std::make_pair(sessionId,new SessionData(userId,userType,currentTime))); 

我的地图迭代(我需要每循环访问currentTime while循环内

sessionMap_map_t::iterator itSessionMap = sessionMap.begin(); 
    while(itSessionMap != sessionMap.end()) 
    { 
     //TODO: Get currentTime 

    } 
+0

与您的问题无关,但您的术语有点偏离。 ['std :: map'](http://en.cppreference.com/w/cpp/container/map)类不是*“* hashmap”。它通常使用树来实现。 ['std :: unordered_map'](http://en.cppreference.com/w/cpp/container/unordered_map)*是*“hashmap”。 –

+0

谢谢。我是C++新手,所以一些术语对我来说还不清楚。我已经更正了地图。 – Pik93

回答

1
SessionData *sessionData; 
sessionMap.insert(std::make_pair(sessionId, sessionData)); 

使用iterater穿越地图:

for (auto itr = sessionMap.begin(); itr != sessionMap.end() ++itr) { 
    std::string sessionId = itr->first(); 
    SessionData *sessionData = itr->second(); 

    // do something with userId and userType 

    // to get current time 
    std::string currentTime = sessionData->currentTime; 
} 
+0

感谢您的评论和代码。它不可能像我发布一样使用类?在你的例子中,你以前不给userId和userType赋值,但是你需要正确吗? – Pik93

+0

我已经如此编辑了。谢谢;) – Pik93

+0

@ Pik93是的,这只是显示语法。你应该在使用它之前初始化'sessionData'。 –

0

下面是解

#include <iostream> 
#include <string> 
#include <map> 
using namespace std; 
class SessionData 
{ 

public: 
    SessionData(std::string pUserId, std::string pUserType) 
    { 
     userId = pUserId; 
     userType = pUserType; 
    } 

    ~SessionData() 
    { 
    } 

    std::string userId; 
    std::string userType; 

}; 

int main() 
{ 
    std::map<std::string, SessionData*> sessionMap; 
    **sessionMap.insert(std::make_pair("Test_Session_12345",new SessionData("1234","Test")));** 
} 
+0

感谢您的解决方案:) – Pik93

1

你的做法是不是完全错误的。 假设...

std::string pUserId = "MyFirstUser"; 
std::string pUserType = "testType"; 

...然后将它像如下...

// A short method to insert a new entry... 
sessionMap[pUserId] = new SessionData(pUserId, pUserType); 
// using operator[] is a more elegant alternative to calling insert(...value_type(...)) 

...现在它在你的sessionMap有效的条目,映射pUserId '独一无二' 来SessionData的一个实例。 但请注意,SessionData实例是

  1. 通过弱指针引用。谨防潜在的内存泄漏。擦除条目或清除地图不会删除实例!

  2. 在其中一个实例中更改成员'userId'不会隐式地将密钥映射更改为该实例。

对于那些谁抱怨我没有检查其插入检查下面第二个示例前项...

// A more "verifying" method to insert a second entry... 
pUserId = "MySecondUser"; 
std::map<std::string, SessionData*>::const_iterator itEntry = sessionMap.find(pUserId); 
if (sessionMap.end() == itEntry) 
{ // Either "old"-style... 
    // sessionMap.insert(std::map<std::string, SessionData*>::value_type(pUserId, new SessionData(pUserId, pUserType)); 
    // ...or again elegant style... 
    sessionMap[pUserId] = new SessionData(pUserId, pUserType); 
} 
else 
{ // Example error handling in case of non-unique keys... 
    throw string("error: Entry '") + pUserId + string("' is not unique"); 
} 

更改已插入的条目的关键不改变顺序在地图中的元素。 即使您使用std :: set <>或任何其他技巧都不会更改此操作,因为如果更改条目成员,则不会重新调用派生二叉树的排序逻辑。

在你想找到你createTime并且在超过30分钟的我建议以下情况下将其删除的情况下...

// I assume you have/implement a class 'MyTimeClass' and a static function initializing it with the current time... 
MyTimeClass currenTime = MyTimeClass::currentTime(); 
// Let's define an intermediate not-expiring-time... 
MyTimeClass oldestNotExpiringTime = currentTime - MyTimeClass(30min); // 30min is pseudo code and shall be replaced by the parameters defining the 30 minutes of expiration, however your MyTimeClass is defined 
// Now, let's iterate all entries in the map using the non-const iterator (to be able to modify the map by deleting entries)... 
for (std::map<std::string, SessionData*>::iterator itEntry = sessionMap.begin(); sessionMap.end() != itEntry; /* don't ++itEntry to avoid conflicts with erase() */) 
{ // I assume you have a member 'createTime' of type 'MyTimeClass'... 
    MyTimeClass createTime = itEntry->second.createTime; 
    // ...and I assume it implements an operator<() to compare times... 
    if (createTime < oldestNotExpiringTime) 
    { // this means the createTime is older than the oldest accepted time -> delete it but first copy the iterator to be able to resume iteration after deletion... 
     std::map<std::string, SessionData*>::iterator itToDelete = itEntry; 
     // Iterate the loop-iterator before deleting the entry to avoid access violations (aka SEGFAULT)... 
     ++itEntry; 
     // Now delete the entry... 
     sessionMap.erase(itToDelete); 
    } 
    else 
    { // No reason to delete -> iterate regularily... 
     ++itEntry; 
    } 
} 

这是你迭代到下一个位置是非常重要的,因为删除该条目之前的“旧的“迭代器是一种指向条目的指针,并且也将被删除。迭代已删除的迭代器结果通常在访问violaton(内存异常,SEGFAULT)中。这就是为什么我做这个例外if/else。

+0

感谢您的意见。我有另一个问题: – Pik93

+0

想象一下,我的SessionData有3个字段(userId,userType,createTime)我的sessionIds有验证(例如30分钟),每秒我运行一个函数。这个函数需要遍历所有map,并检查所有sessionIds的所有createTimes。如果某些createTime大于30分钟,我需要删除此sessionId。我的疑问是:如何遍历所有地图,获取createTime(检查当前日期,我知道该怎么做)并删除sessionId。如果我有例如5 sessionIds createTime大于30分钟,我需要在迭代过程中删除所有。检查我的编辑1看到我的代码请 – Pik93

1

下面书写的代码是什么意思? 有人可以告诉我吗? 尤其是构造函数,它是如何工作的?

template<class K, class V> 
class interval_map 
{ 
private: 
    std::map<K, V> m_map; 

public: 
    interval_map(V const& val) 
    { 
     m_map.insert(m_map.begin(), std::make_pair(std::numeric_limits<K>::lowest(), val)); 
    } 
} 
+0

这不是一个答案。本部分仅供解答 –