如何作为一个类成员存储一个正常的distrubution

时间:2017-08-27 23:15:11

标签: c++ boost

我有一个在构造函数中初始化boost::normal_distribution对象的类。如何将此对象存储在成员中,以便它可以在类中的其他位置使用?我想我想存储一个指向boost对象的指针,但是一旦我离开构造函数,对象就会从堆栈中释放出来。所以,我认为我真的想用new在堆上分配正态分发对象,但我不知道如何才能使语法正确。

class Generator 
{
  private:
    boost::variate_generator<boost::mt19937&, 
                             boost::normal_distribution<> > *_var_nor;

  public:
    Generator( int avg_size, int stddev_size )

      PhraseGenerator( size, words );

      boost::mt19937 rng; // I don't seed it on purpouse (it's not relevant)
      boost::normal_distribution<> nd(avg_size, stddev_size);
      boost::variate_generator<boost::mt19937&, 
                               boost::normal_distribution<> > var_nor(rng, nd);

            _var_nor = &var_nor;
    };

    int normal_distrib_value()
    {
        return (*_var_nor)();
    }
};

2 个答案:

答案 0 :(得分:0)

如果您希望Generator类型的所有对象共享同一个成员,则应将其声明为静态。

示例:

// in Generator.h

class Generator 
{
  private:
    static boost::variate_generator<boost::mt19937, 
                             boost::normal_distribution<> > _var_nor;
  // ...
};

// in Generator.cpp
#include "Generator.h"

boost::variate_generator<boost::mt19937, 
   boost::normal_distribution<> > Generator::_var_nor{
       boost::mt19937{}, 
       boost::normal_distribution<>{}
};
// ...

答案 1 :(得分:0)

在您的示例中,一旦构造函数退出,_var_nor将指向不再存在的对象,并且稍后取消引用它的任何尝试都将是未定义的行为。您可以new normal_distribution,但这并不是new所需要的唯一内容。请注意,variate_generator的第一个模板参数是boost::mt19937&,因此它只存储对Mersenne Twister的引用,而不是复制它,因此您也遇到了相同的问题。您可以将参数类型更改为非参考,或new mt19937

无论如何,这是一个更简单的解决方案,它不涉及指针或new。只需为您的班级成员mt19937normal_distributionvariate_generator成员。请记住,您声明它们的顺序非常重要,因为它是order they'll be initialized in

class Generator 
{
  private:
    boost::mt19937 _rng;
    boost::normal_distribution<> _nd;
    boost::variate_generator<boost::mt19937&, 
                             boost::normal_distribution<> > _var_nor;

  public:
    Generator( int avg_size, int stddev_size )
    : _nd(avg_size, stddev_size)
    , _var_nor(_rng, _nd)
    {
        PhraseGenerator( size, words );
    }

    int normal_distrib_value()
    {
        return _var_nor();
    }
};