多维数组的越界检查 我正在读一本关于安全C++的书。在这里,作者提到了如何避免越界数组读取。这里提到了如何避免多维数组的越界数组读取。这里作者使用了如下链接所示的operator()函数,而不是operator[],并给出了以下解释

多维数组的越界检查 我正在读一本关于安全C++的书。在这里,作者提到了如何避免越界数组读取。这里提到了如何避免多维数组的越界数组读取。这里作者使用了如下链接所示的operator()函数,而不是operator[],并给出了以下解释,c++,C++,请注意,要访问多维数组,我们需要使用多个[]运算符,例如矩阵[i][j],或者使用单个()运算符,例如矩阵(i,j) 如果让[]运算符返回指向第i行第0个元素的T*指针,则可以实现第一种方法。然而,这使我们无法诊断列索引超出范围,这违背了在运行时捕获bug的目的。当然,我们可以创建一些模板类,其中包含对行的智能引用,返回使用第一个操作符([i])的实例,然后在第二个操作符([j])中使用边界检查 我的问题是,作者所说的“创建一些模板类,其中包括对行的智能引用,返回使用第一个运算符([i])的实例

请注意,要访问多维数组,我们需要使用多个
[]
运算符,例如矩阵[i][j],或者使用单个
()
运算符,例如矩阵(i,j)

如果让
[]
运算符返回指向第i行第0个元素的
T*
指针,则可以实现第一种方法。然而,这使我们无法诊断列索引超出范围,这违背了在运行时捕获bug的目的。当然,我们可以创建一些模板类,其中包含对行的智能引用,返回使用第一个操作符(
[i]
)的实例,然后在第二个操作符(
[j]
)中使用边界检查

我的问题是,作者所说的“创建一些模板类,其中包括对行的智能引用,返回使用第一个运算符(
[i]
)的实例,然后在第二个运算符(
[j]
)中使用边界检查”是什么意思?请求提供示例代码,我们如何在C++中实现上述逻辑?


感谢您的时间和帮助。

基本思路如下:

#include <vector>
#include <iostream>

template <class T>
class matrix { 
    size_t cols;
    size_t rows;
    std::vector<T> data;

    class row_proxy {  // This class is the part the question really asked about
        size_t row;
        matrix &m;
    public:
        row_proxy(matrix &m, size_t row) : row(row), m(m) {}

        T &operator[](size_t col) {
            if (row >= m.rows || col >= m.cols) // Note: row & col are indices not array count
                throw std::logic_error("Bad index");
            return m.data[row * m.cols + col];
        }
    };

public:

    matrix(size_t cols, size_t rows) : rows(rows), cols(cols), data(rows*cols) {}

    row_proxy operator[](size_t row) { 
        return row_proxy(*this, row);
    }
};

int main() { 
    matrix<int> m(3, 3);

    for (int i=0; i<3; i++)   // fill the matrix with identifiable numbers
        for (int j=0; j<3; j++)
            m[i][j] = i * 100 + j;

    for (int i=0; i<3; i++) { // show the content
        for (int j=0; j<3; j++)
            std::cout << m[i][j] << "\t";
        std::cout << "\n";
    }

    try {                     // test the bounds checking.
        m[4][1] = 21;
    }
    catch(std::logic_error &e) { 
        std::cerr << e.what(); 
    }

    return 0;
}
#包括
#包括
模板
类矩阵{
尺码;
行大小;
std::矢量数据;
类row_proxy{//这个类是问题真正涉及的部分
行大小;
矩阵&m;
公众:
行代理(矩阵&m,大小为行):行(行),m(m){}
T&T运算符[](大小列){
if(row>=m.rows | | col>=m.cols)//注意:row&col是索引而不是数组计数
抛出std::逻辑_错误(“坏索引”);
返回m.data[行*m.cols+col];
}
};
公众:
矩阵(大小列,大小列):行(行),列(列),数据(行*列){}
行代理运算符[](行大小){
返回行\代理(*此,行);
}
};
int main(){
矩阵m(3,3);

对于(int i=0;i而言,基本思想如下所示:

#include <vector>
#include <iostream>

template <class T>
class matrix { 
    size_t cols;
    size_t rows;
    std::vector<T> data;

    class row_proxy {  // This class is the part the question really asked about
        size_t row;
        matrix &m;
    public:
        row_proxy(matrix &m, size_t row) : row(row), m(m) {}

        T &operator[](size_t col) {
            if (row >= m.rows || col >= m.cols) // Note: row & col are indices not array count
                throw std::logic_error("Bad index");
            return m.data[row * m.cols + col];
        }
    };

public:

    matrix(size_t cols, size_t rows) : rows(rows), cols(cols), data(rows*cols) {}

    row_proxy operator[](size_t row) { 
        return row_proxy(*this, row);
    }
};

int main() { 
    matrix<int> m(3, 3);

    for (int i=0; i<3; i++)   // fill the matrix with identifiable numbers
        for (int j=0; j<3; j++)
            m[i][j] = i * 100 + j;

    for (int i=0; i<3; i++) { // show the content
        for (int j=0; j<3; j++)
            std::cout << m[i][j] << "\t";
        std::cout << "\n";
    }

    try {                     // test the bounds checking.
        m[4][1] = 21;
    }
    catch(std::logic_error &e) { 
        std::cerr << e.what(); 
    }

    return 0;
}
#包括
#包括
模板
类矩阵{
尺码;
行大小;
std::矢量数据;
类row_proxy{//这个类是问题真正涉及的部分
行大小;
矩阵&m;
公众:
行代理(矩阵&m,大小为行):行(行),m(m){}
T&T运算符[](大小列){
if(row>=m.rows | | col>=m.cols)//注意:row&col是索引而不是数组计数
抛出std::逻辑_错误(“坏索引”);
返回m.data[行*m.cols+col];
}
};
公众:
矩阵(大小列,大小列):行(行),列(列),数据(行*列){}
行代理运算符[](行大小){
返回行\代理(*此,行);
}
};
int main(){
矩阵m(3,3);

对于(int i=0;我能告诉我们您目前为止在这方面的努力吗?当问题是“这意味着什么”时,到目前为止怎么会有努力?作者的意思是您返回一个对象,该对象包含对索引行开头的嵌入引用,并且在该对象中,大小限制使其(对象)被重写
操作符[]
可以使用与第一个维度的索引方式类似的方法对该维度进行索引检查。只需使用第二种方法。
[[]]
被高估了。您能告诉我们您迄今为止在这方面所做的努力吗?当问题是“这意味着什么”时,到目前为止如何努力?作者意味着您返回一个对象,该对象包含对索引行开头的嵌入引用,并且在该对象中,大小限制使其(对象)被覆盖
操作符[]
可以检查索引该维度,类似于第一个维度的索引方式。只需使用第二种方法。
[]
被高估了。谢谢你的详细解释。现在我明白了作者的意思。谢谢你的详细解释。现在我明白了作者的意思。