Статические члены ошибочно инициализируются как пустые строки - PullRequest
0 голосов
/ 09 мая 2018

У меня есть три файла:

api.h * * 1004

class HttpApi{
 public:
    static bool postData(string json);

 private:
    static  string remoteHost;
    static  string port;
    static  string url;
};

api.cpp

string HttpApi::remoteHost = Config::getInstance().getRemoteServer();
string HttpApi::port = Config::getInstance().getPort();
string HttpApi::url="/api/miner";

bool HttpApi::postData(string json)
{
    //Here I print Config::getInstance.getRemoteServer(), the value is correct set here

    cout<<"Start resolve "<< remoteHost<<"   "<<port<<endl;
    cout<<"Succeed in resolving "<<endl;

}

и наконец:

int main(int argc, char** argv)
{
    Config&  config = Config::getInstance();
    cout<<"Start loading configuration "<<endl;
    config.loadConfig("config.ini");

    HttpApi::postData("hello world");
}

Проблема для меня заключается в том, что инициализация двух членов remoteHost, port недопустима: во время выполнения оба пусты.

Здесь Config - это одноэлементный класс, который считывает значения из config.ini. Он имеет несколько членов, таких как remoteHost и port.

Почему оба статических элемента пусты и как я могу это исправить?

1 Ответ

0 голосов
/ 09 мая 2018

Поскольку вы не предоставили Минимальный, Полный и Проверяемый пример , можно только догадываться, что произойдет.

Во-первых, статические данные-члены классов инициализируются в самом начале вашей программы, в неуказанном порядке, до того, как main() вызывается 1 . Это означает, что

string HttpApi::remoteHost = Config::getInstance().getRemoteServer();
string HttpApi::port = Config::getInstance().getPort();

оценивается до

config.loadConfig("config.ini");

Во-вторых, если мы сделаем предположение, что Config::getInstance() возвращает построенный экземпляр по умолчанию до вызова любого loadConfig, и если мы также предположим, что построенный по умолчанию Config является только набором, скажем, пустых строк, то мы можем точно сказать, что HttpApi::remoteHost и HttpApi::port будут инициализированы из пустых строк.

Наконец, возможное решение - удалить анти-шаблон Singleton или определить способ HttpApi для использования уже загруженной конфигурации:

void HttpApi::load(Config const& conf) // obviously declared as static
{
    remoteHost = conf.getRemoteServer();
    port       = conf.getPort();
}

int main(int argc, char** argv)
{
    Config& config = Config::getInstance();
    std::cout << "Start loading configuration\n";
    config.loadConfig("config.ini");
    HttpApi::load(config);
    HttpApi::postData("hello world");
}

1) Это не совсем так, для любопытных читателей:

[class.static.data]/6

Статические члены данных инициализируются и уничтожаются точно так же, как нелокальные переменные ([basic.start.static], [basic.start.dynamic], [basic.start.term]).

и

[basic.start.dynamic]/4

Определяется реализацией, выполняется ли динамическая инициализация нелокальной не встроенной переменной со статической длительностью хранения перед первым оператором main или откладывается.

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