C++ 在C++;

C++ 在C++;,c++,static-members,C++,Static Members,我不确定我在我的标题中使用了正确的术语,但以下是我试图做的: 我有一个轻量级粒子类(简化),它要求出生和墙碰撞的随机行为。我想在课堂上保留这方面的设施。据我所知,静态成员只创建一次,并且可以在类的所有实例之间共享 对于random number generator对象,我想调用一次seed方法,但我不确定如何执行此操作,因为大多数示例使用纯静态变量或函数 粒子。h: #include <random> class Particle { public: Par

我不确定我在我的标题中使用了正确的术语,但以下是我试图做的:

我有一个轻量级粒子类(简化),它要求出生和墙碰撞的随机行为。我想在课堂上保留这方面的设施。据我所知,静态成员只创建一次,并且可以在类的所有实例之间共享

对于random number generator对象,我想调用一次seed方法,但我不确定如何执行此操作,因为大多数示例使用纯静态变量或函数

粒子。h:

#include <random>

class Particle
{
    public:
        Particle();
    private:
        static std::default_random_engine pRNG;
        static std::uniform_real_distribution<> dist(0, 1);
};
#包括
类粒子
{
公众:
粒子();
私人:
静态标准::默认随机引擎pRNG;
静态标准:均匀实分布区(0,1);
};
粒子.cpp

#include "particle.h"
#include <ctime>

std::default_random_engine Particle::pRNG.seed(time(NULL)); // <- wrong, help!

Particle::Particle() {}

// methods, etc.
#包括“particle.h”
#包括

std::default_random_引擎粒子::pRNG.seed(时间(NULL));// 实现这一点的简单方法是:创建一个名为“AutoInitRNG”的类,该类在其构造函数中为
default\u random\u引擎
种子。并使该类成为粒子的静态成员变量。大概是这样的:

class AutoInitRNG
{
public:
    std::default_random_engine pRNG;

    AutoInitRNG()
    {
        pRNG.seed(time(NULL));
    }
};

class Particle
{
//...
private:
    static AutoInitRNG RNG;
};

std::default_random_引擎粒子::pRNG.seed(时间(NULL));// 您希望在构建
Particle::pRNG
之后调用
seed
,并且只调用一次。任何具有静态存储持续时间的内容都只初始化一次。如果具有静态存储持续时间和动态初始化的两个定义位于同一个转换单元中,则它们将始终按该顺序初始化(并按相反顺序销毁)

所以你只需要第二个定义。诀窍是编一些东西,这样你就可以定义它

// In header:
class Particle {
    // ...
private:
    static std::default_random_engine pRNG;
    class RNG_Setup_;
    friend class Particle::RNG_Setup_;
};

// In source:
std::default_random_engine Particle::pRNG;
class Particle::RNG_Setup_ {
    RNG_Setup_() { Particle::pRNG.seed(time(nullptr)); }
    static RNG_Setup_ setup_instance;
};
Particle::RNG_Setup_::setup_instance{};

制作一个只有一个实例的
ParticleRGN
类?谢谢大家的回答。我选择泰勒的答案,因为它是我最容易掌握和实施的。我在Particle.h中添加了简单的RNG类,并使其成为Particle的静态成员(staticrngprng)。在Particle.cpp中,我在顶部定义了RNG Particle::pRNG。@Adrian如果对多个类执行此操作,请小心。静态初始化的顺序/时间在很大程度上取决于编译器,因此您可能会遇到由两个类获得完全相同的种子值而导致的奇怪行为。我以前也遇到过这种事。