【问题标题】:Global scoped objects are not initialized recursively?全局范围的对象没有递归初始化?
【发布时间】:2016-07-25 01:44:55
【问题描述】:

我的项目中有以下代码:

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

如您所见,我在尝试访问 MONTH_DAY_MAP_LY 时收到 std::out_of_range 错误。在调试会话之后,我发现这是因为Date 的构造函数在任何其他函数(甚至是主函数)之前被调用。但是我也在标准中找到了这个页面:

命名空间范围的对象的动态初始化(8.5、9.4、12.1、12.6.1)是否在main的第一条语句之前完成是实现定义的。如果初始化延迟到 main 的第一个语句之后的某个时间点,它应该发生在第一次使用与要初始化的对象相同的翻译单元中定义的任何函数或对象之前。

由于此规则同时适用于 Date date 和来自 constants.h 的对象,我不知道为什么链接器会初始化 Date date 和仅来自 constants.hints。

【问题讨论】:

标签: c++ linker global-variables


【解决方案1】:

MONTH_DAY_MAP_LYstd::map&lt;QString, std::pair&lt;int, int&gt;&gt;,所以你应该使用std::map::atQString 作为参数而不是元素索引:constants::MONTH_DAY_MAP_LY.at("January").second

来自文档:

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

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

返回对元素的映射值的引用,其键等效于键。如果不存在这样的元素,则会抛出 std::out_of_range 类型的异常。

【讨论】:

  • 实际上我确实在我的代码中使用了 QString 元素,只是想表明MONTH_DAY_MAP_LY 中根本没有元素。很抱歉造成混淆,将解决它。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-10-03
  • 2019-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-29
相关资源
最近更新 更多