私は私のプロジェクトで次のコードがあります。グローバルスコープオブジェクトは再帰的に初期化されませんか?
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
というエラーが発生します。デバッグセッションの後、私はそれが起こったことを理解しました。Date
のコンストラクタは他の関数より前に呼び出されています(メインでも)。しかし、私はまたこのページを標準で見つけました:
名前空間スコープのオブジェクトの動的初期化(8.5,9.4,12.1,12.6.1)が最初のステートメントの前に行われるかどうかは実装定義ですメインの初期化がmainの最初のステートメントの後のある時点に延期されている場合、初期化されるオブジェクトと同じ翻訳単位で定義された関数またはオブジェクトの最初の使用の前に行われます。
この規則は、リンカーはconstants.h
からDate date
だけint
Sを初期化し、なぜ私にはわからないconstants.h
からDate date
とオブジェクトの両方に適用されますので。 constants::MONTH_DAY_MAP_LY.at("January").second
:あなたが代わりに要素のインデックスの引数としてQString
でstd::map::at
を使用する必要がありますので
[the * static initialization order fiasco *](http://stackoverflow.com/q/3035422/440558)を参照してください。特に、[最高の投票回答]の最初の段落を読んでください(http://stackoverflow.com/a/3036852/440558)。 –