作为静态成员的STL容器的内存分配

时间:2021-10-27 17:00:43

I have the following class used to access global registry variables.

我有以下类用于访问全局注册表变量。

template <typename T> using RegistryMap = std::unordered_map <std::string, T *>;
template <typename T> class Registry {
  static RegistryMap<T> registry;

public:
  static T* get(const std::string& name) {
    auto it = registry.find(name);
    return it == registry.end() ? nullptr : it->second;
  }

  static const RegistryMap<T>& getAll() {
    return registry;
  }

 static bool add(const std::string &name, T *object) {
    T* &store = registry[name];
    if (store)
      return false;
    else {
      store = object;
      return true;
    }
  }
};

template <typename T> 
RegistryMap<T> Registry<T>::registry = RegistryMap<T>();

I find that calls to the getAll method return different memory addresses, and I think my understanding of static members and object construction is faulty. I had thought that by declaring registry as static, each Registry template class would allocate memory for a RegistryMap, which would just be a pointer to the STL container on the heap. If I saved a reference to the map (the return value of getAll), I could refer to the STL container even after it gets modified.

我发现对getAll方法的调用返回不同的内存地址,我认为我对静态成员和对象构造的理解是错误的。我原以为通过将注册表声明为静态,每个注册表模板类都会为RegistryMap分配内存,这只是指向堆上STL容器的指针。如果我保存了对地图的引用(getAll的返回值),我甚至可以在修改后引用STL容器。

Instead, getAll returns a reference of the current state of the map, but as things are added/deleted from the RegistryMap, getAll returns new addresses (specifically, old saved references of the map do not show the additional values.

相反,getAll返回地图当前状态的引用,但是当从RegistryMap添加/删除内容时,getAll返回新地址(具体地说,旧保存的地图引用不显示其他值。

Why would this be?

为什么会这样?

Edit:

auto t1 = Registry<void>::getAll();
Registry<void>::add("TESTING", nullptr);
auto t2 = Registry<void>::getAll();

Stepped through the preceding test in VS2013 debugger. t1 has size 0. t2 has size 1 and I can see ("TESTING", nullptr) inside.

在VS2013调试器中逐步完成前面的测试。 t1的大小为0. t2的大小为1,我可以在里面看到(“TESTING”,nullptr)。

1 个解决方案

#1


3  

auto t1 = Registry<void>::getAll();

This makes a copy of the map. You want a reference.

这制作了地图的副本。你想要一个参考。

auto& t1 = Registry<void>::getAll();
//  ^

#1


3  

auto t1 = Registry<void>::getAll();

This makes a copy of the map. You want a reference.

这制作了地图的副本。你想要一个参考。

auto& t1 = Registry<void>::getAll();
//  ^