在类的私有部分中声明数组

时间:2011-10-03 16:38:49

标签: c++ arrays compiler-errors private-members

我有一个类,并且该类的输入的一部分是可变长度的向量(称为数据)(假设它具有长度N)。我在函数之后包含了这个:

    N = data_->size();

在类的私有部分中,我想声明一个数组double A[N][N];。但是,当我尝试这样做时,我会得到一些说法

  

错误:“N不是类型名称,静态或枚举器”。

如何创建数组A[N][N]

很抱歉,如果这已经在其他地方解释过了,因为我对c ++很新,所以甚至不知道要找什么!

编辑 - 附加代码:

    class foo {     
    public:
        foo (std::vector &data)
    : data(data_)
    {
        N = data_->size();
        M =  /* four times the last member of data (which is a vector of positive integers)*/
    }

    private:
      double A[M][M];

    void foo(void)
    {
      for (std::size_t i=1; i<=M; ++i)
        {
          A[i][i] = 1;
        }
    }
    };

希望有某种意义......我怎么能定义A [M] [M]?也许它不可能为M做,因为M是数据的函数。如果M不可能,N?

是否可能

我能想到的一个可能性是,我可以将A设为std::vector< std::vector<double> > A,然后将大量的0或其他内容推入其中,然后修改这些值......

4 个答案:

答案 0 :(得分:5)

如果您使用的是std :: vector类,则必须使用以下句子在data_类的函数中创建向量(例如构造函数):

A = vector<vector<double> >(N, vector<double>(N, 0));

括号的第一个参数是矢量的大小,第二个参数是其上的数据类型。

对不起我的英语,我是西班牙语,我的英语不是很好。

答案 1 :(得分:4)

你做不到。数组是类型,它们必须在编译时知道。这包括他们的尺寸。因此,您不能将动态数组作为类的一部分。你得到的最接近的是指向手动分配的数组的指针,但实际上它基本上是std::vector。因此,最简单的解决方案可能只是拥有一个矢量矢量,或者可能是一个大小为N * N的矢量,您可以在步幅j + N * i中访问它。

示例:

std::vector< std::vector<int> > v(N, std::vector<int>(N));

或者:

std::vector< std::vector<int> > v;
//...
v.resize(N, std::vector<int>(N));

访问权限:v[2][4] = 8;


更新:由于您编辑了答案,因此您可以编写类似的内容来获取N * 4n向量,其中data.back() == n

std::vector<unsigned int> data = get_data(); // given!

std::vector< std::vector<double> > v(data.size(), std::vector<double>(4 * data.back()));

答案 2 :(得分:1)

嗯...这里有几个问题......

  • 未声明NM(在构造函数中或作为foo的成员)
  • 您正在尝试初始化未声明的成员data(您的意思是data_(data),因为语法为member(expression),而不是expression(member))
  • 构造函数的参数是不完整的类型:它必须是std::vector< sometype >;如果你想要它是通用的,你需要使用模板或从boost
  • 获得一些帮助
  • 您没有初始化您声明的唯一成员变量(A
  • void foo(void)是一个问题,因为它不是构造函数(没有类型)但使用类名
  • 的正确语法

让我们建立更接近你想要的东西

从课程foo开始:

class foo {
};

使用构造函数采用类型std::vector<double>

的单个参数
class foo {
public:
  foo(std::vector<double> &data);
};

您想要使用数据

初始化成员变量
class foo {
private:
  std::vector<double> data_;
public:
  foo(std::vector<double> &data)
    :data_(data)
  {};
};

此时我会注意到我通常将非平凡构造函数的定义放在类声明中,而是在实现文件中,因此我会能够使用构造函数的声明将成员变量的声明放在公共部分下面。但是为了紧凑,我会在这里离开。

您想要捕获并存储数据的大小

class foo {
private:
  std::vector<double> data_;
  size_t N;
 public:
  foo(std::vector<double> &data)
    :data_(data)
    ,N(data.size())
  {};

};

此时我们还没有制作出您想要的多维存储,但现在您已经做出了一些关于如何管理存储的决定。如果您使用Kerrek SB's approach,这看起来像

class foo {
private:
  std::vector<double> data_;
  size_t N;
  std::vector< std::vector<double> > A;
public:
  foo(std::vector<double> &data)
    :data_(data)
    ,N(data.size())
    ,A()
  {
    A.resize(N);
    for (size_t i=0; i<N; ++i) {
      A[i].resize(N);
    }
  };
};

答案 3 :(得分:0)

如果您不想自己管理内存,则需要使用智能指针动态创建它。

double **A;

在构造函数中:

A = new double *[N];
for(i=0;i<N;++i)
{
  A[i] = new double [N];
}

不是你必须在析构函数中调用delete,现在要遵守三条规则,你必须有一个复制构造函数和赋值运算符......在这里使用智能指针更好:参见Boost smart pointer help page.