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

Memory Allocation of STL-Containers as Static Members

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

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>();

我发现调用 getAll 方法 return 不同的内存地址,我认为我对静态成员和对象构造的理解是错误的。 我原以为通过将 registry 声明为静态的,每个 Registry 模板 class 都会为 RegistryMap 分配内存,它只是指向堆上 STL 容器的指针。如果我保存了对地图的引用(getAll 的 return 值),即使它被修改后我也可以引用 STL 容器。

相反,getAll returns 是映射当前状态的引用,但是由于 RegistryMap 中的内容是 added/deleted,getAll returns 新地址(具体来说,地图的旧保存参考不显示附加值。

为什么会这样?

编辑:

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

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

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

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

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