的基本思路看起來是這樣的:
#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)
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;
}
所以,當我們創建了一個矩陣,我們保存它的大小在rows
和cols
。當我們在矩陣上使用operator[]
時,它不會嘗試直接返回對矩陣中某個項的引用 - 而是返回一個代理類的實例,用於跟蹤行和矩陣,提供和自己的operator[]
。
因此,當您使用matrix[a][b]
時,第一個將a
和matrix
保存到代理對象中。然後在該代理對象上調用[b]
部分。這將檢查a
和b
是否在我們爲矩陣保存的範圍內,如果是,則返回對矢量中正確對象的引用。否則,它會拋出一個std::Logic_error
(可能不是最好的選擇 - 只是第一次發生在我身上)。
我應該補充說,這個總體思路有很多變化。僅舉一個例子,您可以在編譯時指定數組的大小,但將大小作爲模板參數傳遞。這可以有一些優點 - 例如,matrix<int, 2, 3>
和matrix<int, 3, 2>
是完全不同的類型,所以您不能意外地將一個指派給另一個。它也可能有一些缺點(最明顯的是,你需要需要來知道編譯時的大小,否則根本不會工作)。
您能不能通過您的努力啓發我們 – 2013-03-14 05:31:11
當問題是「這意味着什麼」時,到目前爲止還有什麼努力? – FoolishSeth 2013-03-14 05:32:43
作者意味着你返回一個包含嵌入引用的對象,該嵌入引用指向索引行的開始,並且在該對象內的大小限制,以便覆蓋'operator []'的邊界(對象)可以邊界檢查索引該維度類似於第一個維度被編入索引。 – WhozCraig 2013-03-14 05:36:33