C ++ Map将向量下标超出范围

时间:2017-01-03 05:18:46

标签: c++ stl unordered-map

我正在尝试创建一个将其实例存储在地图中的类:

class Apple {
    public: 
        static Apple* getApple(const std::string &name) {
             auto it = allApples.find(name);

             if (it == allApples.end()) // if this apple doesnt exist, make a new one
                 return new Apple(name); 
             else // if the apple exists, return its pointer
                 return it->second;
        }
    private:
        static std::unordered_map<std::string, Apple*> allApples =                
            std::unordered_map<std::string, Apple*>();

        Apple(const std::string &name) {
            // create an apple
            allApples.insert({ name, this });
        }
}

现在,我创建了一些存储静态Apples的类:

class Orange {
     static Apple *myOrangeApple;
}

myOrangeApple = Apple::getApple("orange");

当我运行程序时,它在getApple()方法的第一行崩溃,向量下标超出范围错误。我试过环顾四周,但我找不到任何处理地图的解决方案,而且超出了范围错误。我从一些研究中得到的最好的猜测是它是关于静态顺序初始化的东西,但我真的不太确定。

3 个答案:

答案 0 :(得分:1)

使用函数范围的静态对象。

...
private:
   std::unordered_map<std::string, Apple*>& allApples() {
      static std::unordered_map<std::string, Apple*> apples;
      return apples;
   }

这是对抗静态初始化顺序惨败的标准方法之一。它的工作原理是,当第一次执行块时,保证块范围静态对象被初始化。

如果以这种方式管理的对象之间存在相互依赖关系,则此方法将不起作用。

答案 1 :(得分:0)

首先,你的getApple方法应该是静态的,你应该在类之外初始化类成员(静态成员)。试试这个 -

class Apple {
    public: 
        static Apple* getApple(const std::string &name) {
             auto it = allApples.find(name);

             if (it == allApples.end()) // if this apple doesnt exist, make a new one
                 return new Apple(name); 
             else // if the apple exists, return its pointer
                 return it->second;
        }
    private:
        static std::unordered_map<std::string, Apple*> allApples; 

        Apple(const std::string &name) {
            // create an apple
            allApples.insert({ name, this });
        }
};

std::unordered_map<std::string, Apple*> Apple::allApples = std::unordered_map<std::string, Apple*>();

class Orange {
     static Apple *myOrangeApple;
};

Apple * Orange::myOrangeApple=Apple::getApple("orange");

答案 2 :(得分:0)

您在初始化之前访问allApples。在您输入main之前,无法保证allApples已构建,因此访问它是明确的禁忌。

拥有将自己添加到容器的类是一个坏主意,但在全局对象中执行它确实非常糟糕。不要那样做。