【问题标题】:Initialize public attributes with argument from class constructor in c++使用 C++ 中类构造函数的参数初始化公共属性
【发布时间】:2012-11-09 07:47:01
【问题描述】:

我在 .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 并且它们的构造函数将我的类构造函数也接受的参数作为输入。

即:我的 PoreNetwork 类的构造函数采用 1 个参数 esize,它是一个 int,这也是其属性 Radiuses 和 States 的构造函数的参数。

【问题讨论】:

  • 您在构造函数中所做的是声明局部变量并对其进行初始化。

标签: c++ constructor initialization boost-multi-array


【解决方案1】:

初始化成员的最好方法是使用初始化列表。 但是您仍然需要注意成员声明顺序和初始化顺序。

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,则初始化 State 和 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 放在成员列表中的 States/Radiuses 前面,则会收到编译器警告。

【讨论】:

    【解决方案2】:

    使用初始化列表:

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

    【讨论】:

    • hmm,一个问题,你应该把 Size(esize) 放在初始化列表的顶部,否则初始化状态和半径是未定义的行为
    • 啊,好点,我的意思是用 esize 替换 Size ,但忘记了.. 已修复; Size(esize) 不能放在最前面,因为成员应该按照声明的顺序初始化,并且在类定义中 Size 排在最后
    【解决方案3】:

    成员变量构造函数是这样调用的:

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

    这意味着在将构造函数参数应用于成员变量之前,很难在正文中使用它们。如果你不能调用 resize() (或类似的东西),使用 boost::extents 之类的函数通常是唯一的选择。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多