Make initialization variables accessible to several attributes initialization methods

时间:2019-01-12 09:17:29

标签: c++

I write a class using sparse matrices. It happens that for both of them, their non-zeros are on the same (i,j)s. As I have to compute these (i,j)s, I'd prefer to have to do it only once.

Currently, I do it separately and my constructor looks like this:

class C
{
    private:
        matrix matA;
        matrix matA;
        holder ijs;

    private:
        matrix initMatA();
        matrix initMatA();
        holder init_ijs(int, int);

    public:
        C(int, int);
};

C::C(int foo, int bar) : init_ijs(foo, bar), matA(initMatA()), matB(initMatB())
{
}

as I've read that it is best practice to use initialization list (and actually, when I first wrote it, if I remember correctly it was impossible to instantiate my matrices otherwise (EDIT: a default constructor seems to fix it?)). If it was Python, I could write something like

def initMats(foo, bar):
    ...
    return matA, matB

If think the C++ way would be something like

void initMats(int foo, int bar, matrix &matA, matrix &matB)
{
    ...
}

but I guess I cannot pass reference to objects that have not yet been constructed. Any clue on a way to solve this? My idea was to first create the (i,j)s list as an attribute to my class so I can later use it in my initA and initB methods, but I will not be needing it afterward I don't think it's the best way to do.

2 个答案:

答案 0 :(得分:1)

如果我对问题的理解正确,那么您希望:

  • 以两个稀疏矩阵(或类似矩阵)作为输入
  • 为两个矩阵计算IJ
  • 在继续之前
  • 对他们两个都应用IJ
  • 使用修改后的矩阵构造Class。

约束是矩阵不可默认构造。

我想我会这样做:

// A class to hold the result of computing ij
struct ij_holder
{
    // whatever goes here
};

// a sparse matrix class
struct sparse_matrix
{
    // let's say it's not default-constructible
    sparse_matrix(int, int , int , int);
};

// apply ij to sparse matrix m, returning the modified matrix
sparse_matrix apply(ij_holder const& ij, sparse_matrix m)
{
    // whatever goes here to modify m

    return m;
}

// compute ij from two matricies
ij_holder compute_ij(sparse_matrix const& a, sparse_matrix const& b);


struct Class
{
    // public constructor written in terms of private constructor
    Class(sparse_matrix const& foo, sparse_matrix const& bar)
    : Class (compute_ij(foo, bar), foo, bar)
    {}

private:
    // private constructor
    Class(ij_holder ij, sparse_matrix const& foo, sparse_matrix const& bar)
    : foo_(apply(ij, foo))
    , bar_(apply(ij, bar))
    {}


sparse_matrix foo_;
sparse_matrix bar_;

};

答案 1 :(得分:1)

在C ++中,初始化方法不是惯用的。使用构造函数。

您可以使用委托构造器(C ++ 11及更高版本)实现所需的功能。首先,您需要matrix类的构造函数,该构造函数接受一个(i,j)列表。

  using ijlist = ...; //probably some kind of an array
  class matrix {
      ...
      matrix(const ijlist& ijs) { ... }
      ...
  };

然后,您为C编写一个构造函数,该构造函数接受一个ijlist并将其传递给两个矩阵数据成员:

  class C {
      ...
      matrix matA, matB;
      ...
      C(const ijlist& ijs) : matA(ijs), matB(ijs) { ... }

现在,您可以在辅助函数中计算(i,j)列表,并将其从任何其他构造函数传递给此构造函数:

  C() : C(compute_ijs()) { ... }