C ++类映射对象

时间:2017-04-18 07:34:52

标签: c++

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

这是我的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;
};

现在我找不到解决问题的方法了。如何将地图保存到sessionIduserId userType?我的char sessionId[80]已经通过我的算法生成sessionId(算法对于这种情况并不重要)。我是c ++的新人,但我认为就是这样:

sessionMap[sessionId].insert();

但我不知道如何插入userIduserType,因为我的地图是关键&lt; - &gt;对象..密钥为sessionId,对象为我的班级SessionData,其中包含userIduserType

编辑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里面的循环

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

    }

3 个答案:

答案 0 :(得分: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;
}

答案 1 :(得分: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")));**
}

答案 2 :(得分:0)

你的方法并非完全错误。 我们假设......

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&#39; unique&#39;到SessionData的一个实例。 但要注意SessionData实例是

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

  2. 更改会员&#39; userId&#39;在其中一个实例中,不会隐式更改到实例的键映射。

  3. 对于那些抱怨我在插入之前没有检查条目的人,请检查第二个例子......

    // 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&lt;&gt;或者任何其他技巧都不会改变这一点,因为如果对条目成员进行更改,则不会重新调用派生二叉树的排序逻辑。

    如果你想找到你的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;
        }
    }
    

    在删除条目之前迭代到下一个位置非常重要,因为&#34; old&#34;迭代器是一种指向该条目的指针,也将被删除。迭代删除的迭代器通常会产生访问中提问题(内存异常,SEGFAULT)。这就是为什么我在/ else时发出这个异常。