Delete object managed by shared_ptr when only one link is left

I have std::map<const char*, std::shared_ptr<Resource, ResourceDeleter>>one that acts like a ResourceDatabase. The element in is std::mapinserted when someone requests a Resource that is not already in std::map(otherwise, it will be sent out std::map). Similarly, when a resource is no longer in use, it should be deleted. In ResourceDeleterI will delete the entry from std::map. The problem is that it is ResourceDeleternever called, because it is std::mapstill there std::shared_ptr. When an element is inserted in std::map, there will always be 2 std::shared_ptr- one for the code that needs the Resource, and one in std::map. When the first one is std::shared_ptrdeleted, I need to remove the resource from std::map.

+4
source share
2 answers

You should use std :: weak_ptr on your std :: map.

#include <iostream>
#include <memory>

struct A {
  std::string hello() { return "hello"; }
  ~A() { std::cout << "Destructor ~A() called" << std::endl; }
};

void use(std::weak_ptr<A> const& wp)
{
  if (auto spt = wp.lock())
  {
    std::cout << "Accessing object... " << spt->hello() << "\n";
  }
  else
  {
    std::cout << "use(): object was deleted\n";
  }
}

int main()
{
  std::weak_ptr<A> wp;
  {
    std::shared_ptr<A> sp = std::make_shared<A>();
    wp = sp;
    use(wp);
    std::cout << "Destructing sp" << std::endl;
  }
  use(wp);
  std::cout << "Destructing wp" << std::endl;
}

Conclusion:

Access to the object ... hello
Destruction sp The
destructor ~ A () is called
use (): the object has been deleted

Destruction wp

+2
source

As I understand the problem, the goal is that when you delete the last shared pointer to a resource, the resource must be removed from the ResourceMap and then deleted. As you say, this is not possible if the shared resource pointer is stored in the ResourceMap, since the shared map pointer will always be the last shared resource pointer.

, . - (std::weak_ptr) . , , ResourceMap. std::map ( std::unordered_map), , mapped_type .

map map::emplace.

ResourceDeleter , , ( ). ( shared_ptr) .

shared_ptr, shared_pointer std::pair<const key_type, mapped_type>. , * p->second, *p.

+1

All Articles