2017-08-27 4 views
1

私は、コンストラクタの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)(); 
    } 
}; 

答えて

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<>{} 
}; 
// ... 
+0

'variate_generator'はデフォルトで申し訳ありませんが – Praetorian

+0

を構築することができない、OPは分布はコンストラクタ引数から構築したい部分を除いて、私はコンパイルされません:) –

+1

作品を今、すべてをキャッチすることはできません。 – Praetorian

0

は、コンストラクタ出ると、_var_norはもはや存在しないオブジェクトを指すようになりますし、それを逆参照しようとすると、後に未定義の動作になります。 newnormal_distributionとすることができますが、それはnewに必要なことだけではありません。 variate_generatorの最初のテンプレートパラメータはboost::mt19937&なので、それはMersenne Twisterへの参照を保存しているだけで、コピーするのではないので、同じ問題もあります。パラメータタイプを非参照、またはnewmt19937に変更することもできます。

とにかく、単純な解決策があり、ポインタや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(); 
    } 
}; 
+0

詳細な応答、Praetorianありがとう。それはうまくいった。修正されたコンストラクタについて...私はその部分を推測します... ":_nd(avg_size、stddev_size)、_var_nor(_rng、_nd)"は_ndおよび_var_norオブジェクトのコンストラクタを呼び出しています...正しいと仮定した場合、なぜcouldnジェネレータのコンストラクタの本体でこれらのコンストラクタを呼び出すだけですか? – Mercutio

+0

@ user1318209これは、デフォルトでメンバーを構築してから、コンストラクター本体に異なる値を割り当てる*ことを意味します。これは、 'variate_generator'がデフォルトで構成可能でないため、この場合コンパイルされません。 mem-initializerリストを好む理由については、https://stackoverflow.com/q/926752/241631を参照してください。 – Praetorian

関連する問題