在main之外和变量声明之前调用srand

时间:2016-05-05 01:26:14

标签: c++ class object random

我需要在我的程序中使用rand(),但事实是它在类上调用,我创建的对象需要在全局范围内,所以我需要在main之前调用srand()全球范围有办法吗?

#include <stdlib.h>
#include <iostream>
#include <time.h>
#include "Electron.h"

srand(time(0));
Electron el1;
Electron el2;
Electron el3;
Electron el;


int main(int argc, char** argv){
    ...
}

2 个答案:

答案 0 :(得分:4)

在相同翻译单元中声明的全局范围对象将按其声明的顺序构造。因此,您可以声明一个存根类,并使其构造函数调用srand()。

class invoke_srand {
public:
     invoke_srand()
     {
         srand(time(0));
     }
};

static invoke_srand do_invoke_srand;

Electron el1;
Electron el2;
Electron el3;
Electron el;

但是,未指定在不同翻译单元中构建全局范围对象的顺序,因此您只能保证在此翻译单元的全局作用域之前调用srand()已构造,并且您无法保证其他翻译单元中全局范围对象的构造顺序。

答案 1 :(得分:1)

要确保在srand的任何通话之前一次调用rand,无论使用哪个翻译单元,您都可以执行此操作:

auto my_rand()
    -> int
{
    static bool const dummy = (srand( time( 0 ) ), true);
    return rand();
}

dummy的第一次调用中,my_rand只会初始化一次。

所以只需使用my_rand而不是直接使用rand

在其他新闻中:

  • 全局变量是Evil™ 它们引入了无形的数据流和影响线,使得很难理解程序中发生了什么。

  • C ++ 11引入了比rand更好的随机生成器 但是,它们更复杂。我甚至不能在这里把它们命名为我,我必须要查找它们。但是,如果您正在进行模拟,我认为您会发现它是值得的。

  • time是熵的不良来源 来自<chrono>的高分辨率时钟会好得多。否则,对于大致在同一时间(一秒钟内)开始的运行,您冒着相同的种子风险。