gpt4 book ai didi

c++ - 了解何时从 std::map 中删除关联的用户数据

转载 作者:行者123 更新时间:2023-11-30 02:55:06 24 4
gpt4 key购买 nike

我有一个地址映射,可以让我用对象存储任意数据。基本上,我正在编写的一个库有一个模板化函数,它最终可以用对象存储任意数据。

std::map<void *, MyUserData>

这是有效的,直到传入的对象被销毁,将其用户数据留在 map 中。我也想删除关联的用户数据,所以我需要以某种方式监听传入对象的析构函数,

一些说明问题的示例代码:

#include <map>
#include <memory>


struct MyUserData
{
int someNum;
};

std::map<void *, MyUserData> myMap;

template <typename T>
registerObject<T>(const std::shared_ptr<T> & _object)
{
static inc = 0;

myMap[(void *)&_object->get()].someNum = inc++;
}

struct MyObject
{
int asdf;
};

int main(int _argc, char ** _argv)
{
auto obj = std::make_shared<MyObject>();
obj->asdf = 5;

registerObject(obj);

obj = 0;

//The user data is still there. I want it to be removed at this point.
}

我目前的解决方案是在 shared_ptr 上设置自定义删除器。这会在调用对象的析构函数时向我发出信号,并告诉我何时删除关联的用户数据。不幸的是,这需要我的库创建 shared_ptr,因为没有“set_deleter”函数。它必须在构造函数中初始化。

mylib::make_shared<T>(); //Annoying!

我也可以让用户手动删除他们的对象:

mylib::unregister<T>(); //Equally annoying!

我的目标是能够在没有任何事先注册的情况下延迟添加对象。

总而言之,我想检测对象何时被删除,并知道何时从 std::map 中删除它的拷贝。

有什么建议吗?

附言我是否应该担心将用户数据留在 map 中?为一个对象分配与先前删除的对象相同地址的可能性有多大? (就我的库而言,它最终会收到相同的用户数据。)

编辑:我认为我最初没有很好地表达我的问题。重写。

最佳答案

从你的代码示例来看,它看起来像是外部接口(interface)

template <typename T>
registerObject<T>(const std::shared_ptr<T> & _object);

我假设某处有一个 get 风格的 API。我们称之为getRegisteredData . (它可能是内部的。)

在问题的范围内,我会使用 std::weak_ptr<void>而不是 void* , 作为 std::weak_ptr<T>可以判断何时不再有对对象的“强引用”,但不会通过维护引用来阻止对象被删除。

std::map<std::weak_ptr<void>, MyUserData> myMap;

template <typename T>
registerObject<T>(const std::shared_ptr<T> & _object)
{
static inc = 0;

Internal_RemoveDeadObjects();

myMap[std::weak_ptr<void>(_object)].someNum = inc++;
}

template <typename T>
MyUserData getRegisteredData(const std::shared_ptr<T> & _object)
{
Internal_RemoveDeadObjects();
return myMap[std::weak_ptr<void>(_object)];
}

void Internal_RemoveDeadObjects()
{
auto iter = myMap.cbegin();
while (iter != myMap.cend())
{
auto& weakPtr = (*iter).first;
const bool needsRemoval = !(weakPtr.expired());

if (needsRemoval)
{
auto itemToRemove = iter;
++iter;
myMap.erase(itemToRemove);
}
else
{
++iter;
}
}
}

基本上,std::weak_ptrstd::shared_ptr合作和std::weak_ptr可以检测何时不再有std::shared_ptr对相关对象的引用。一旦出现这种情况,我们就可以从 myMap 中删除辅助数据。 .我正在使用 myMap 的两个接口(interface), 你的 registerObject和我的 getRegisteredData作为方便的地方打电话Internal_RemoveDeadObjects执行清理。

是的,这遍历了 myMap 的全部内容每次注册新对象或请求注册数据时。根据需要进行修改或尝试不同的设计。

您问“我是否应该担心将用户数据留在映射中?一个对象被分配到与先前删除的对象相同的地址的可能性有多大?”根据我的经验,绝对非零,所以不要这样做。 :-)

关于c++ - 了解何时从 std::map<void *, ...> 中删除关联的用户数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16681610/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com