STL-Containers作为静态成员的内存分配

时间:2015-05-30 03:33:43

标签: c++ templates stl static-members

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

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

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

为什么会这样?

编辑:

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

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

1 个答案:

答案 0 :(得分:3)

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

这是地图的副本。你想要一个参考。

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