2015-06-05 31 views
2

在下面的代码中,RandomCharSource应该根据请求简单地返回一个随机字符。它的构造函数正在初始化一个mt19937,uniform_int_distribution<int>和一个random_device。但是,当我实例化我的对象时,我得到了段错误。正在初始化<random>构造函数中的类导致段错误

当我在下面的bar()函数中手动创建这些随机类时,它工作正常。

我在做什么错?这里是否有初始化顺序问题?我正在使用GCC 4.7.3。

#include <random> 
#include <iostream> 

class RandomCharSource 
{ 
public: 
    explicit RandomCharSource() : _re{_rd()}, _dist{0, 255} {}; 
    inline char get_next_char() { return _dist(_re); }; 
private: 
    std::mt19937 _re; 
    std::uniform_int_distribution<int> _dist; 
    std::random_device _rd; 
}; 

void foo() 
{ 
    RandomCharSource s; 
    std::cout << s.get_next_char() << std::endl; 
} 

void bar() 
{ 
    std::random_device _rd; 
    std::mt19937 _re{_rd()}; 
    std::uniform_int_distribution<int> _dist{0,255}; 
    std::cout << (char)_dist(_re) << std::endl; 
} 

int main() 
{ 
    bar(); // Works OK 
    foo(); // Segfault 

    return 0; 
} 

回答

6

这是因为你的初始化顺序

class RandomCharSource 
{ 
public: 
    explicit RandomCharSource() : _re{_rd()}, _dist{0, 255} {}; 
    inline char get_next_char() { return _dist(_re); }; 
private: 
    std::mt19937 _re; 
    std::uniform_int_distribution<int> _dist; 
    std::random_device _rd; 
}; 

您需要_re之前有_rd。成员按照他们在课堂中声明的顺序进行初始化。因此,当您尝试使用_rd初始化_re时,_rd尚未初始化。

从标准§12.6.2.13(重点煤矿)

在非委托构造函数,以下面的顺序初始化前进:

13.1 - 首先,只对最派生类的构造函数(1.8)中,虚拟基类按照它们出现在基类的有向无环图的深度优先从左到右遍历的顺序进行初始化,其中“从左到右”是基类的出现顺序派生类base-specifier-list中的类。
13.2 - 然后,直接基类以声明顺序初始化,因为它们出现在base-specifier-list中(不管mem-initializer的顺序如何)。
13.3 - 然后,非静态数据成员按照它们在类定义中声明的顺序进行初始化(不管mem-initializers的顺序如何)。
13.4 - 最后,执行构造函数体的复合语句。
[注意:声明顺序的要求是确保基本和成员子对象在 相反的初始化顺序中被销毁。 - 注意]

+0

感谢您的参考。 – Steve

相关问题