使用unique_ptr来管理三维数组

Using a unique_ptr to manage a three dimensional array

本文关键字:管理 三维 数组 ptr unique 使用      更新时间:2023-10-16

我使用以下方式分配了三维:

board = new char**[depth];
    for (int d = 0; d < depth; d++)
    {
        board[d] = new char*[rows];
        for (int i = 0; i < rows; i++) {
            board[d][i] = new char[cols];
            for (int j = 0; j < cols; j++) {
                board[d][i][j] = 'k';
            }
        }
    }

现在,我想使用unique_ptr来管理它,但是我不知道如何使用unique_ptr公开的接口启动这种结构。

表面上,您可以这样写:

std::unique_ptr<std::unique_ptr<std::unique_ptr<char[]>[]>[]>board = 
    std::make_unique<std::unique_ptr<std::unique_ptr<char[]>[]>[]>(depth);
for (int d = 0; d < depth; d++)
{
    board[d] = std::make_unique<std::unique_ptr<char[]>[]>(rows);
    for (int i = 0; i < rows; i++) {
        board[d][i] = std::make_unique<char[]>(cols);
        for (int j = 0; j < cols; j++) {
            board[d][i][j] = 'k';
        }
    }
}

这将以您期望的方式或无数的方式工作。

但是圣意大利面条代码,蝙蝠侠!这是一些严重的草率代码!

您可以使用std::vector这样简化它,这是代表阵列阵列的更自然的结构:

std::vector<std::vector<std::vector<char>>> board;
board.resize(depth);
for (int d = 0; d < depth; d++)
{
    board[d].resize(rows);
    for (int i = 0; i < rows; i++) {
        board[d][i].resize(cols);
        for (int j = 0; j < cols; j++) {
            board[d][i][j] = 'k';
        }
    }
}

但是,鉴于您正在编写本质上是一个3D矩形矩阵,因此像这样写它仍然没有多大意义。相反,让我们这样做:

size_t get_index(size_t i, size_t j, size_t k, size_t rows, size_t cols, size_t depth) {
    if(i > rows || j > cols || k > depth) throw std::runtime_error("Out of bounds!");
    return k * rows * cols + j * rows + i;
}
size_t get_size(size_t rows, size_t cols, size_t depth) {
    return rows * cols * depth;
}
int main() {
    size_t rows = 15, cols = 10; depth = 5;
    std::vector<char> board(get_size(rows, cols, depth));
    for(size_t d = 0; d < depth; d++) {
        for(size_t r = 0; r < rows; r++) {
            for(size_t c = 0; c < cols; c++) {
                board[get_index(r, c, d, rows, cols, depth)] = 'k';
            }
        }
    }
}

您可以考虑将所有这些包装到Matrix类中,该类别自行处理所有这些翻译。然后,您可以编写看起来像这样的代码:

int main() {
    size_t rows = 15, cols = 10; depth = 5;
    Matrix<char> board(rows, cols, depth);
    for(size_t d = 0; d < board.get_depth(); d++) {
        for(size_t r = 0; r < board.get_rows(); r++) {
            for(size_t c = 0; c < board.get_cols(); c++) {
                board(r, c, d) = 'k';
            }
        }
    }
}

哪个更干净,更容易维护,如果您使您的Matrix类通用,则可以重复使用。