2017-04-18 149 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

這不是一個答案。本部分僅供解答 –