Инициализировать открытые атрибуты с аргументом из конструктора класса в переполнении стека

У меня есть класс, реализованный в файле .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 */

Моя проблема в том, что атрибуты PoreNetwork :: Radiuses и PoreNetwork :: States, кажется, не инициализируются, когда я вызываю это из моего main.cpp.

Насколько я понимаю, Радиусы и Состояния в моем .cpp не являются теми, которые определены в моем файле заголовков, потому что я переопределяю их.

Моя проблема заключается в следующем: как мне определить и инициализировать эти 2 атрибута в моем классе, зная, что они Boost :: multi_array и что их конструктор принимает в качестве входных данных параметры, которые принимает и мой конструктор класса.

то есть: конструктор моего класса PoreNetwork принимает 1 аргумент esize, который является int, который также является аргументом конструктора для его атрибутов Radiuses и States.

0

Решение

Лучший способ инициализировать элементы — использовать список инициализации.
Но вам все равно нужно обратить внимание на порядок декларирования членов и инициализировать заказы.

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;
}

Если вы не инициализируете Size в первую очередь, то инициализировать состояния, а Radiuses и Size еще не инициализированы, это неопределенное поведение.

 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)

Если вы не поставите Size перед State / Radiuses в списке участников, вы получите предупреждение компилятора.

2

Другие решения

используйте список инициализаторов:

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

Конструкторы переменных-членов называются так:

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

Это означает, что трудно работать с аргументами конструктора внутри тела, прежде чем применять их к переменным-членам. Использование функции, такой как boost :: extents, если часто единственный вариант, если вы не можете вызвать resize () (или что-то подобное).

0
По вопросам рекламы [email protected]