2016-07-24 3 views
0

У меня есть следующий код в моем проекте:Объекты с глобальным объектом не инициализируются рекурсивно?

mainwindow.cpp

#include "date.h" 

Date date; //extern from date.h <- Error when instantinating this one 

MainWindow::MainWindow(){//...} 

date.cpp

#include "date.h" 
#include "consants.h" 

//..Stuff 
Date::Date() 
{ 
    //Use const int variable from "constants.h" 
    year = constants::START_YEAR; //Works, START_YEAR is initialized 
    Month month(m, y); 
} 
Month::Month(int month, int year) 
{ 
    //Use const std::map<QString, std::pair<int,int>> from "constants.h" 
    day_count = constants::MONTH_DAY_MAP_LY.at("January").second //ERROR, MONTH_DAY_MAP_LY is not initialized 
} 

constants.h

namespace constants { 
const int START_YEAR = 2016; 
const int YEAR_COUNT = 83; 

const QList<QString> MONTH { "January", "February", "March", 
     "April", "May", "June", "July", "August", "September", "October", "November", "December"}; 

const std::map<QString, std::pair<int, int>> MONTH_DAY_MAP{ 
    {MONTH[0], std::make_pair(0, 31)}, {MONTH[1], std::make_pair(1, 28)}, {MONTH[2], std::make_pair(2, 31)}, 
    {MONTH[3], std::make_pair(3, 30)}, {MONTH[4], std::make_pair(4, 31)}, {MONTH[5], std::make_pair(5, 30)}, 
    {MONTH[6], std::make_pair(6, 31)}, {MONTH[7], std::make_pair(7, 31)}, {MONTH[8], std::make_pair(8, 30)}, 
    {MONTH[9], std::make_pair(9, 31)}, {MONTH[10], std::make_pair(10, 30)}, {MONTH[11], std::make_pair(11, 31)} 
}; 
const std::map<QString, std::pair<int, int>> MONTH_DAY_MAP_LY { 
    {MONTH[0], std::make_pair(0, 31)}, {MONTH[1], std::make_pair(1, 29)}, {MONTH[2], std::make_pair(2, 31)}, 
    {MONTH[3], std::make_pair(3, 30)}, {MONTH[4], std::make_pair(4, 31)}, {MONTH[5], std::make_pair(5, 30)}, 
    {MONTH[6], std::make_pair(6, 31)}, {MONTH[7], std::make_pair(7, 31)}, {MONTH[8], std::make_pair(8, 30)}, 
    {MONTH[9], std::make_pair(9, 31)}, {MONTH[10], std::make_pair(10, 30)}, {MONTH[11], std::make_pair(11, 31)} 
}; 
} 

Как вы видите, я получаю ошибку std::out_of_range при попытке получить доступ к MONTH_DAY_MAP_LY. После сеанса отладки я понял, что это происходит потому, что конструктор Date вызывается перед любой другой функцией (даже основной). Но я также нашел эту страницу в стандарте:

Она определяется реализацией или нет динамической инициализации (8.5, 9.4, 12.1, 12.6.1) объекта из области видимости пространства имен производится перед первым оператором основного. Если инициализация отложена до некоторого момента времени после первого утверждения main, она должна произойти до первого использования любой функции или объекта, определенных в той же самой единицы перевода, что и объект, который будет инициализирован.

Поскольку это правило относится и к Date date и объекты из constants.h я не знаю, почему линкер инициализирует Date date и только int s из constants.h.

+2

Подробнее о [статической ошибке инициализации фиаско *] (http://stackoverflow.com/q/3035422/440558). Особенно прочтите первый абзац [самый высокий голосовой ответ] (http://stackoverflow.com/a/3036852/440558). –

ответ

0

MONTH_DAY_MAP_LY является std::map<QString, std::pair<int, int>>, так что вы должны использовать std::map::at с QString в качестве аргумента вместо индекса элемента: constants::MONTH_DAY_MAP_LY.at("January").second.

Из документации:

T& at(const Key& key); (1) (так как C++ 11)

const T & at(const Key& key) const; (2) (так как C++ 11)

Возвращает ссылку на отображенный значение элемента с ключом, эквивалентным ключу. Если такой элемент не существует, генерируется исключение типа std::out_of_range.

+0

Фактически я действительно использую элемент QString в своем коде, просто хотел показать, что элементов в MONTH_DAY_MAP_LY' вообще нет. извините за смущение, исправит это. – 7Y3RPXK3ETDCNRDD

Смежные вопросы