带指针的模板,创建2d数组

Templates with pointers, creating 2d array

本文关键字:创建 2d 数组 指针      更新时间:2023-10-16

我在模板和指针方面遇到了一个小问题。我正在尝试为一些不同类型的不同矩阵创建一个2d数组。我必须在有意义的地方使用模板和引用。我的主要功能是这样的,我不允许更改它:

int main(){
    int row, column;
    cin >> row;
    cin >> column;
    int** M1;
    double** M2;
    reserve(M1, row, column);
    reserve(M2, row, column);
    return 0;
}

所以我的储备函数看起来是这样的:

template <typename S>
void reserve(S &x, int row, int column){
  x = new S*[row];
  for(int i = 0; i < row; ++i) {
      x[i] = new S[column];
  }
}   

我的问题是,我没有得到这个函数的解决方案。我想尽一切办法都试过了,但都没用。我认为问题是我不能正确地将类型**指针与类型参数结合使用。在我上面发布的版本中,我收到了错误,比如:

error: cannot convert ‘int****’ to ‘int**’ in assignment x = new S*[row];

如果有人能帮我修复这个功能,我会很高兴的。

reserve的签名更改为这个应该可以修复编译错误

template <typename S>
void reserve(S **&x, int row, int column)

或者,您可以实现reserve,以便它返回新分配的数组

template <typename S>
S** reserve(int row, int column)
{
    S** x = new S*[row];
    for (int i = 0; i < row; ++i) {
        x[i] = new S[column];
    }
    return x;
}

使用完delete []后,请记住使用它删除数组:)

也许这样的东西会对你有所帮助;尝试将整个概念封装到一个类对象中,如下所示:

template<typename T>
class Matrix {
public:
    typedef std::vector<T> Row; 
private:
    std::vector<Row> Mat;
    unsigned numberRows;
    unsigned numberColumns;
public:
    Matrix();
    explicit Matrix( std::vector<Row>& vRows );
    Matrix( unsigned numRows, unsigned numColumns );
    Matrix( unsigned numRows, unsigned numColumns, T** data );
    ~Matrix();
private:
    void reserve( unsigned int numRows, unsigned int numColumns );
}; 

其中这个reserve()方法是类对象的一部分,只有这个类可以访问它。这将在实现它的多个构造函数时充当类的辅助函数。如果你想对元素使用动态内存,可以扩展为:

template<typename T>
class Matrix {
public:
   typedef std::vector<std::shared_ptr<T>> Row;
private:
    std::vector<Row> Mat;
    // All Else Would Be The Same; Only The Internal Methods Would Slightly
    // Vary Due To The Use Of Smart Pointer And Dynamic Memory.
};

然后,在您的主体中,这将简化代码。

int main() {
    // Using Default Constructor
    Matrix<float> fMat1;   
    // Using std::vector<Row> To Construct A Matrix
    Matrix<int>::Row row1;
    Matrix<int>::Row row2;
    Matrix<int>::Row row3;
    std::vector<Matrix<int>::Row> vRows
    Matrix<int>   iMat2( vRows );
    // A Construct That Knows The Size Of The Matrix; 
    // But Doesn't Have The Data
    Matrix<double> dMat3( 4, 4 ); // This Will Create A Size Of 4x4 Of
                                  // Doubles And Initialize Everything To 0 
    // Same As Above, But Passing In Raw Data By Double Pointer.
    float** pData = nullptr; 
    // Populate Pointer's Elements
    unsigned int row, col;
    // Store Size Of Row & Col Based On Pointer's Elements
    Matrix<float>( row, col, pData );
    return 0;
}

就这样!构造函数不应该那么难实现。如果你只处理堆栈对象,类的第一个定义会起作用,但如果你需要所有对象的动态内存,第二个定义会满足你的需求,智能指针的使用会使动态内存的清理更干净、更容易、更安全。不太容易发生内存泄漏。

这也将允许您在创建矩阵时拥有可用数据时创建矩阵;或者使一个空的矩阵容器可用于留出内存,以便稍后准备填充它。您只需要添加必要的方法来设置、获取数据元素,以及执行基本操作所需的任何适当的运算符重载。也许是一些公共方法来对数据进行常见的工作,或者测试数据是否在矩阵中,等等。

因为这个矩阵类就是模板;它不仅仅受制于基本的原始日期类型。它可以存储类对象、结构、函数指针、事件、线程、文件等等!