Гарантируется ли инициализация статических переменных родителя перед статическими переменными потомка? - PullRequest
2 голосов
/ 30 июня 2019

У меня C ++ код выглядит следующим образом

Parent.hpp

class Parent {
    static std::map<std::string, std::function<void()>> list;
}

Parent.cpp

#include "Parent.hpp"
std::map<std::string, std::function<void()>> Parent::list;

Child.hpp

#include "Parent.hpp"
class Child : Parent {
    static bool isRegistered = registerComponent();
    std::function<void(GameObject* go, void* arr)> add;
    static bool registerComponent();

Child.cpp

#include "Child.hpp"
    static bool Child::isRegistered = registerComponent();
    std::function<void(GameObject* go, void* arr)> Child::add = []() {
        //do something
    }
    static bool Child::registerComponent() {
        if (add) {
            list["child"] = Child::add;
            return true;
        }
        else return false
    }

list гарантированно инициализируется до того, как я позвоню registerComponent()?Я прочитал этот пост Когда инициализируются статические члены класса C ++? Я думаю, что это не гарантировано, но я не уверен на 100%.

1 Ответ

2 голосов
/ 30 июня 2019

Нет, это не так. Как вы и написали, нет порядка порядка инициализации между list и статическими членами Child.

Что гарантируется , так это то, что статические данные инициализируются перед любым использованием (в соответствии с правилом одного определения) любой функции в их единице перевода. Так что если вы сделаете registerComponent членом Parent, все будет хорошо между классом Parent и его потомками.

class Parent {
    static std::map<std::string, std::function<void()>> list;
  protected:
    // Implemented in the same TU where list is defined
    static bool registerComponent(std::string k, std::function<void()> v);
};

Теперь любой дочерний класс, вызывающий registerComponent, будет использовать функцию из модуля перевода, который определил list, поэтому list обязательно будет инициализирован перед выполнением функции.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...