2016-07-24 16 views
0

Ich habe das in meinem Projekt folgenden Code:Globale Objekte mit Gültigkeitsbereich werden nicht rekursiv initialisiert?

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

Wie Sie sehen, bekomme ich den std::out_of_range Fehler beim Versuch, auf MONTH_DAY_MAP_LY zuzugreifen. Nach der Debugging-Sitzung habe ich herausgefunden, dass dies passiert, weil der Konstruktor Date vor jeder anderen Funktion aufgerufen wird (sogar main). Aber ich fand diese Seite auch in der Norm:

Es ist die Implementierung definiert, ob die dynamische Initialisierung (8.5, 9.4, 12.1, 12.6.1) ein Objekts von Namespacebereich ist vor der ersten Anweisung getan von Haupt. Wenn die Initialisierung auf einen Zeitpunkt nach der ersten Anweisung von main verschoben wird, soll sie vor der ersten Verwendung einer Funktion oder eines Objekts erfolgen, die in der gleichen Übersetzungseinheit definiert sind wie das zu initialisierende Objekt.

Da diese Regel sowohl Date date bezieht und Objekte aus constants.h Ich weiß nicht, warum Linker Date date und nur int s von constants.h initialisiert.

+2

Lesen Sie über [die * statische Initialisierungsreihenfolge Fiasko *] (http://Stackoverflow.com/q/3035422/440558). Lesen Sie besonders den ersten Absatz von [die Antwort mit der höchsten Wahl] (http://stackoverflow.com/a/3036852/440558). –

Antwort

0

MONTH_DAY_MAP_LY ist std::map<QString, std::pair<int, int>>, so dass Sie std::map::at mit QString als Argument statt Elementindex verwenden sollte: constants::MONTH_DAY_MAP_LY.at("January").second.

Aus der Dokumentation:

T& at(const Key& key); (1) (da C++ 11)

const T & at(const Key& key) const; (2) (seit C++ 11)

Gibt einen Verweis auf das abgebildete Wert des Elements mit Schlüssel, der dem Schlüssel entspricht. Wenn kein solches Element existiert, wird eine Ausnahme vom Typ std::out_of_range ausgelöst.

+0

tatsächlich verwende ich QString-Element in meinem Code, wollte nur zeigen, dass es keine Elemente in 'MONTH_DAY_MAP_LY' überhaupt gibt. Entschuldigung für Verwirrung, wird es beheben. – 7Y3RPXK3ETDCNRDD