调用c++中静态成员对象的函数

Calling functions of a static member object in C++

本文关键字:函数 成员对象 静态 c++ 调用      更新时间:2023-10-16

我不确定我在标题中是否使用了正确的术语,但这是我想做的:

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

对于随机数生成器对象,我想调用seed方法一次,但不确定如何做到这一点,因为大多数示例使用普通静态变量或函数。

Particle.h:

#include <random>
class Particle
{
    public:
        Particle();
    private:
        static std::default_random_engine pRNG;
        static std::uniform_real_distribution<> dist(0, 1);
};

Particle.cpp

#include "particle.h"
#include <ctime>
std::default_random_engine Particle::pRNG.seed(time(NULL)); // <- wrong, help!
Particle::Particle() {}
// methods, etc.
seed方法放入Particle构造函数中,我想会在每个出生的粒子上调用它。我能想到的唯一快速hack是向Particle类添加一个bool成员,在第一次seed调用时将其设置为false。

简单的方法:创建一个名为"AutoInitRNG"的类,在其构造函数中播种default_random_engine。把这个类设为粒子的静态成员变量。像这样:

class AutoInitRNG
{
public:
    std::default_random_engine pRNG;
    AutoInitRNG()
    {
        pRNG.seed(time(NULL));
    }
};
class Particle
{
//...
private:
    static AutoInitRNG RNG;
};

std:: default_random_engine粒子::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{};