0

私は次のように.cppファイルに実装されたクラスを持っています:

#include <ctime>
#include <iostream>

// les 3 lib boost/random nécessaire a généré les radiuses
#include "boost/random/mersenne_twister.hpp"
#include "boost/random/normal_distribution.hpp"
#include "boost/random/variate_generator.hpp"
// la lib boost fournissant des arrays multidimensionnels
#include "boost/multi_array.hpp"

#include "porenetwork.h"

using namespace std;

typedef boost::random::mt19937 ENG;
typedef boost::normal_distribution<double> DIST;   // Normal Distribution
typedef boost::variate_generator<ENG,DIST> GEN;    // Variate generator

typedef boost::multi_array<bool, 3> StateNetworkType;
typedef boost::multi_array<double, 3> RadiusNetworkType;
typedef StateNetworkType::index index;
typedef boost::multi_array_types::index_range range;



PoreNetwork::PoreNetwork(int esize)
{
cout << "esize = " << esize << endl;
Size = esize;
StateNetworkType States(boost::extents[Size][Size][Size]);
RadiusNetworkType Radiuses(boost::extents[Size][Size][Size]);

// initialise the Radiuses
ENG eng;
eng.seed(static_cast<unsigned int>(std::time(0)));
DIST dist(0,1);
GEN gen(eng, dist);

for(index i = 0; i != Size; ++i) 
    for(index j = 0; j != Size; ++j)
        for(index k = 0; k != Size; ++k)
            Radiuses[i][j][k] = gen();

}

int PoreNetwork::getSize() {return Size;}

そして、ヘッダー.hファイルで次のように定義されています:

#ifndef PORENETWORK_H
#define PORENETWORK_H

#include "boost/multi_array.hpp"

typedef boost::multi_array<bool, 3> StateNetworkType;
typedef boost::multi_array<double, 3> RadiusNetworkType;

class PoreNetwork
{
public:
    PoreNetwork(int esize);
    int getSize();
    StateNetworkType States;
    RadiusNetworkType Radiuses;

private:
    int Size;
    /* add your private declarations */
};

#endif /* PORENETWORK_H */ 

私の問題は、main.cppからこれを呼び出すと、属性PoreNetwork::RadiusesとPoreNetwork::Statesが初期化されていないように見えることです。

私が理解しているように、.cppの半径と状態は、再定義しているため、ヘッダーファイルで定義されているものではありません。

私の問題は、Boost :: multi_arrayであり、それらのコンストラクターがクラスコンストラクターも取るパラメーターを入力として受け取ることを知って、クラスでこれら2つの属性を定義および初期化する方法です。

つまり、私のPoreNetworkクラスのコンストラクターは、intである1つの引数esizeを取ります。これは、属性RadiusesおよびStatesのコンストラクターの引数でもあります。

4

3 に答える 3

2

メンバーを初期化する最良の方法は、初期化リストを使用することです。ただし、メンバー宣言の順序と初期化の順序には注意を払う必要があります。

class PoreNetwork
{
private: 
    int Size;  // note, put Size in front of States/Radiuses members
public:
    PoreNetwork(int esize);
    int getSize();
    StateNetworkType States;
    RadiusNetworkType Radiuses;
};

PoreNetwork::PoreNetwork(int esize)
: Size(esize),        // important to initialise Size first
  States(boost::extents[Size][Size][Size]),
  Radiuses(boost::extents[Size][Size][Size]) 
{
  cout << "esize = " << esize << endl;
}

サイズを最初に初期化しない場合、状態と半径を初期化するのは未定義の動作であり、サイズはまだ初期化されていません。

 PoreNetwork::PoreNetwork(int esize)
    : States(boost::extents[Size][Size][Size]),      // Undefined behavior as Size is not initialised yet
      Radiuses(boost::extents[Size][Size][Size]),
      Size(esize) 

メンバーリストのStates/Radiusesの前にSizeを入れないと、コンパイラの警告が表示されます。

于 2012-11-09T08:00:42.913 に答える
0

イニシャライザリストを使用します。

PoreNetwork::PoreNetwork(int esize) :
  States(boost::extents[esize][esize][esize]),
  Radiuses(boost::extents[esize][esize][esize]),
  Size(esize) 
{
...
}
于 2012-11-09T07:51:12.760 に答える
0

メンバー変数コンストラクターは、次のように呼び出されます。

PoreNetwork::PoreNetwork(int esize) :
  States(boost::extents[esize][esize][esize]),
  Radiuses(boost::extents[esize][esize][esize])
{
  ...
}

これは、メンバー変数に適用する前に、本体内のコンストラクター引数を操作するのが難しいことを意味します。resize()(または同様のもの)を呼び出せない場合の唯一のオプションである場合は、boost::extentsなどの関数を使用します。

于 2012-11-09T07:51:20.767 に答える