2016-07-24 8 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というエラーが発生します。デバッグセッションの後、私はそれが起こったことを理解しました。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:あなたが代わりに要素のインデックスの引数としてQStringstd::map::atを使用する必要がありますので

+2

[the * static initialization order fiasco *](http://stackoverflow.com/q/3035422/440558)を参照してください。特に、[最高の投票回答]の最初の段落を読んでください(http://stackoverflow.com/a/3036852/440558)。 –

答えて

0

MONTH_DAY_MAP_LYは、std::map<QString, std::pair<int, int>>です。ドキュメントから

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

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

は、マッピングされた参照を返しますkeyに相当するキーを持つ要素の値。そのような要素が存在しない場合は、タイプstd::out_of_rangeの例外がスローされます。

+0

実際には私のコードでQString要素を使用していますが、 'MONTH_DAY_MAP_LY'に要素が全くないことを示したかっただけです。混乱して申し訳ありません、それを修正します。 – 7Y3RPXK3ETDCNRDD

関連する問題