C ++避免三重指针

时间:2019-02-28 02:58:34

标签: c++ pointers matrix

我正在尝试创建一个X指针数组,该数组引用尺寸为Y乘以16的矩阵。在C ++中,没有使用三重指针的方法吗?

编辑:为问题添加一些上下文。

屏幕上有许多几何图形,每个几何图形都有一个已展平为1x16数组的变换。每个快照代表多个组件中每个组件的转换。因此,矩阵尺寸为16 x num_components x num_snapshots,其中后两个尺寸在运行时已知。最后,我们有许多应用了运动的几何。

我正在创建一个带有三重指针参数的函数,尽管在这种情况下我不能使用三重指针。我还可以通过哪些其他方式(可能通过多个参数)传递数据?最坏的情况是,我考虑将整个3D矩阵展平为一个数组,尽管这似乎是一件草率的事情。还有更好的建议吗?

我现在所拥有的:

function(..., double ***snapshot_transforms, ...)

我想完成的事情:

function (..., <1+ non-triple pointer parameters>, ...)

下面不是我正在创建的函数,它使用三重指针,但显示了数据的全部含义。

static double ***snapshot_transforms_function (int num_snapshots, int num_geometries)
{
    double component_transform[16];

    double ***snapshot_transforms = new double**[num_snapshots];

    for (int i = 0; i < num_snapshots; i++)
    {
        snapshot_transforms[i] = new double*[num_geometries];

        for (int j = 0; j < num_geometries; j++)
        {
            snapshot_transforms[i][j] = new double[16];

            // 4x4 transform put into a 1x16 array with dummy values for each component for each snapshot
            for (int k = 0; k < 16; k++)
                snapshot_transforms[i][j][k] = k;
        }
    }

    return snapshot_transforms;
}

Edit2: 我无法创建新类,也无法使用std之类的C ++功能,因为头文件中公开的函数原型已放入包装器中(这不知道如何解释三重指针)以翻译成其他语言。

Edit3 :在所有人都输入了注释之后,我认为采用扁平数组可能是最好的解决方案。我希望有某种方法可以拆分此三重指针,并使用包括单个指针在内的简单数据类型将这些复杂数据整齐地组织到多个数据块中。尽管我认为这里没有警告,但是我认为没有办法做到这一点。我感谢大家的帮助=)

2 个答案:

答案 0 :(得分:2)

使用std::vector更容易,更好,更容易出错。毕竟,您使用的是C ++,而不是C。我用vector替换了所有C样式的数组指针。使用typedef doublecube可以使您不必一遍又一遍地输入vector<vector<vector<double>>>。除此之外,代码基本上保持与您的代码相同。

如果您实际上不需要伪值,那么我将完全删除最里面的k循环。 reserve将保留实际数据所需的存储空间。

#include <vector>

using std::vector; // so we can just call it "vector"
typedef vector<vector<vector<double>>> doublecube;

static doublecube snapshot_transforms_function (int num_snapshots, int num_geometries)
{    
    // I deleted component_transform. It was never used

    doublecube snapshot_transforms;
    snapshot_transforms.reserve(num_snapshots);

    for (int i = 0; i < num_snapshots; i++)
    {
        snapshot_transforms.at(i).reserve(num_geometries);

        for (int j = 0; j < num_geometries; j++)
        {
            snapshot_transforms.at(i).at(j).reserve(16);

            // 4x4 transform put into a 1x16 array with dummy values for each component for each snapshot
            for (int k = 0; k < 16; k++)
                snapshot_transforms.at(i).at(j).at(k) = k;
        }
    }

    return snapshot_transforms;
}

答案 1 :(得分:1)

添加一点面向对象通常会使代码更易于管理-例如,以下代码创建了一个包含100个Matrix对象的数组,每个Matrix的行数不同。 (如果需要,您也可以更改每个Matrix中的列数,但我将其保留为16):

#include <vector>
#include <memory>  // for shared_ptr (not strictly necessary, but used in main() to avoid unnecessarily copying of Matrix objects)

/** Represents a (numRows x numCols) 2D matrix of doubles */
class Matrix
{
public:
   // constructor
   Matrix(int numRows = 0, int numCols = 0)
      : _numRows(numRows)
      , _numCols(numCols)
   {
      _values.resize(_numRows*_numCols);
      std::fill(_values.begin(), _values.end(), 0.0f);
   }

   // copy constructor
   Matrix(const Matrix & rhs)
      : _numRows(rhs._numRows)
      , _numCols(rhs._numCols)
   {
      _values.resize(_numRows*_numCols);
      std::fill(_values.begin(), _values.end(), 0.0f);
   }

   /** Returns the value at (row/col) */
   double get(int row, int col) const {return _values[(row*_numCols)+col];}

   /** Sets the value at (row/col) to the specified value */
   double set(int row, int col, double val) {return _values[(row*_numCols)+col] = val;}

   /** Assignment operator */
   Matrix & operator = (const Matrix & rhs)
   {
      _numRows = rhs._numRows;
      _numCols = rhs._numCols;
      _values  = rhs._values;
      return *this;
   }

private:
   int _numRows;
   int _numCols;
   std::vector<double> _values;
};

int main(int, char **)
{
   const int numCols = 16;
   std::vector< std::shared_ptr<Matrix> > matrixList;
   for (int i=0; i<100; i++) matrixList.push_back(std::make_shared<Matrix>(i, numCols));

   return 0;
}