在变量声明之前,在main函数外调用srand函数

3

我需要在我的程序中使用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个回答

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
你不需要为此定义一个类(如果需要清理,则另当别论)。只需使用例如 bool const dummy = (srand(time(0)), true); - Cheers and hth. - Alf
这样做会浪费一字节宝贵的内存。没错,RAM现在比以前便宜多了,但我不愿意看到宝贵的字节被浪费掉。 - Sam Varshavchik
1
没有浪费,这是你的一个误解。所以,这个类是一种“过早优化”。更糟糕的是,它是一种无法解决问题的过早优化,因为想象中的问题并不存在。 - Cheers and hth. - Alf

1
为了确保在任何翻译单元中调用rand之前已经调用了一次srand,您可以执行以下操作:
auto my_rand()
    -> int
{
    static bool const dummy = (srand( time( 0 ) ), true);
    return rand();
}

在第一次调用my_rand时,dummy将被初始化一次。

因此,只需使用my_rand而不是直接使用rand


另外的消息:

  • 全局变量是有害的。
    它们引入了不可见的数据流和影响,使得理解程序中正在发生的事情变得困难。

  • C++11引入了比rand更好的随机数生成器。
    然而,它们更加复杂。我甚至不能在这里自己命名它们,我必须查找一下。但是如果你正在进行模拟,你会发现这是值得的。

  • time不是一个很好的熵源。
    来自<chrono>的高分辨率时钟会更好。否则,你可能会在开始时间相近(在一秒内)的运行中使用相同的种子。


谢谢,但我不能在Electron类上调用my_rand,或者我错了吗? - apz2000
1
你不会在那个类上调用它。那不是一个有意义的短语。你需要从那个类的代码中调用它。 - Cheers and hth. - Alf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接