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

C++ Map throws vector subscript out of range

我正在尝试创建一个 class 将其实例存储在地图中,如下所示:

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

现在,我制作了 classes 来存储静态苹果:

class Orange {
     static Apple *myOrangeApple;
}

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

当我 运行 程序时,它在 getApple() 方法的第一行崩溃并出现向量下标超出范围错误。我试过环顾四周,但我真的找不到任何处理地图和这个超出范围错误的解决方案。根据我所做的一些研究,我最好的猜测是它与静态订单初始化有关,但我真的不太确定。

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

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

您在 allApples 初始化之前访问它。在您输入 main 之前,无法保证 allApples 已经构建,因此绝对不能访问它。

让 类 将自己添加到容器中是个坏主意,但在全局对象中这样做确实很糟糕。不要那样做。

使用函数作用域静态对象。

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

这是解决静态初始化顺序失败的标准方法之一。它之所以有效,是因为块作用域静态对象保证在块第一次执行时被初始化。

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