您的方法并非完全错误。
让我们假设...
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 'unique' 映射到 SessionData 的实例。
但请注意,SessionData 实例是
通过弱指针引用。当心潜在的内存泄漏。删除条目或清除地图不会删除实例!
在其中一个实例中更改成员“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;
}
}
在删除条目之前迭代到下一个位置非常重要,因为“旧”迭代器是一种指向条目的指针,也会被删除。迭代已删除的迭代器通常会导致访问违规(内存异常,SEGFAULT)。这就是为什么我在 if/else 中做出这个例外。