我有一个代表对角矩阵的类。我只沿着对角线存放元素,所以我不会浪费一大堆0的空间。但是,我仍然希望能够使用双括号来访问数组中的元素。为了解决这个问题,我使用了一个内部类,如下所示:
template <class T>
class DiagonalMatrix
{
private:
const T ZERO = 0;
int _size;
Vector<T> _data;
class row
{
private:
DiagonalMatrix<T>* _parent;
int _row;
public:
row(DiagonalMatrix<T>* parent, const int row)
: _parent(parent), _row(row) {}
T& operator[](const int i);
};
class const_row
{
private:
const DiagonalMatrix<T>* const _parent;
int _row;
public:
const_row(const DiagonalMatrix<T>* const parent, const int row)
: _parent(parent), _row(row) {}
const T& operator[](const int i) const;
};
friend class row;
friend class const_row;
public:
row operator[] (const int i);
const const_row operator[] (const int i) const;
// other stuff
};
以下是相关定义:
template<class T>
typename DiagonalMatrix<T>::row DiagonalMatrix<T>::operator[](const int i)
{
if (i < 0 || i >= _size)
{
throw IndexOutOfBoundsException(i);
}
return DiagonalMatrix<T>::row(this, i);
}
template <class T>
T& DiagonalMatrix<T>::row::operator[](const int i)
{
if (i < 0 || i >= _parent->_size)
{
throw IndexOutOfBoundsException(i);
}
if (row == col)
{
return _parent->_data[row];
}
// TODO Add a real exception
throw "Cannot modify non-diagonal elements";
}
对于const版本的类似定义,除了const运算符[]之外,返回对常量ZERO的引用,而不是为非对角元素抛出。
所以这就是我的问题:即使我不需要修改任何内容,也会调用非const版本。例如,这会抛出我的错误字符串:
DiagonalMatrix<double> diag(5);
// fill in the diagonal elements with some values
cout << diag[0][2] << endl;
但是,如果我删除运算符的非const版本,它的行为与预期一致并输出0 我也尝试过这样的事情:
T& at(const int row, const int col);
const T& at(const int row, const int col) const;
// in main:
cout << diag.at(0, 2) << endl;
但这有同样的问题。所以我有两个问题:
1)为什么C ++在const版本中选择非const版本的函数,即使我没有分配给结果?不是运营商&lt;&lt;通常通过const&amp;
传递右手对象
2)我怎样才能解决这个问题?如果我可以帮助它,我宁愿没有单独的get()和set()函数。
答案 0 :(得分:6)
1)为什么C ++在const版本中选择非const版本的函数,即使我没有分配给结果?不是运营商&lt;&lt;通常通过const&amp;?
传递右手对象
它选择非const版本,因为diag
不是const对象。
2)我怎样才能解决这个问题?如果我可以帮助它,我宁愿没有单独的get()和set()函数。
您可以为diag
定义一个const refrence并使用它来打印值:
const DiagonalMatrix<double> &const_diag = diag;
cout << diag[0][2] << endl; // call const version
或者您定义一个函数来打印值并传递一个const引用:
void show_diag(const DiagonalMatrix<double> &diag)
{
cout << diag[0][2] << endl; // call const version
}
show_diag(diag);