Что делает const в перегрузке operator ()? - PullRequest
3 голосов
/ 30 марта 2010

У меня есть кодовая база, в которой для класса Matrix эти два определения существуют для оператора ():

template <class T> T& Matrix<T>::operator() (unsigned row, unsigned col)
{
    ......
}


template <class T> T Matrix<T>::operator() (unsigned row, unsigned col) const
{
    ......
}

Я понимаю одно: второй не возвращает ссылку, но что означает const во втором объявлении? Кроме того, какая функция вызывается, когда я говорю mat(i,j)?

Ответы [ 3 ]

6 голосов
/ 30 марта 2010

Какая функция вызывается, зависит от того, является ли экземпляр константным или нет. Первая версия позволяет изменить экземпляр:

 Matrix<int> matrix;
 matrix(0, 0) = 10;

Перегрузка const разрешает доступ только для чтения, если у вас есть экземпляр const (ссылка) Matrix:

 void foo(const Matrix<int>& m)
 {
     int i = m(0, 0);
     //...
     //m(1, 2) = 4; //won't compile
 }

Второй не возвращает ссылку, поскольку намерение состоит в том, чтобы запретить изменение объекта (вы получаете копию значения и, следовательно, не можете изменить экземпляр матрицы).

Здесь T должен быть простым числовым типом, который является дешевым (er) для возврата по значению. Если T также может быть более сложным определяемым пользователем типом, было бы также обычным для const-перегрузок возвращать ссылку на const:

 template <class T>
 class MyContainer
 {
      //..,
      T& operator[](size_t);
      const T& operator[](size_t) const;
 }
3 голосов
/ 30 марта 2010

Константная версия будет вызываться для константных матриц. На неконстантных матрицах будет называться неконстантная версия.

Matrix<int> M;
int i = M(1,2); // Calls non-const version since M is not const
M(1,2) = 7; // Calls non-const version since M is not const

const Matrix<int> MConst;
int j = MConst(1,2); // Calls const version since MConst is const

MConst(1,2) = 4; // Calls the const version since MConst is const.
                 // Probably shouldn't compile .. but might since return value is 
                 // T not const T.

int get_first( const Matrix<int> & m )
{
   return m(0,0); // Calls the const version as m is const reference
}

int set_first( Matrix<int> & m )
{
  m(0,0) = 1; // Calls the non-const version as m is not const
}
1 голос
/ 30 марта 2010

Какая функция вызывается, зависит от того, является ли объект const. Для const объектов const вызывается перегрузка:

const Matrix<...> mat;
const Matrix<...>& matRef = mat;
mat( i, j);//const overload is called;
matRef(i, j); //const overloadis called

Matrix<...> mat2;
mat2(i,j);//non-const is called
Matrix<...>& mat2Ref = mat2;
mat2Ref(i,j);//non-const is called
const Matrix<...>& mat2ConstRef = mat2;
mat2ConstRef(i,j);// const is called

То же самое относится и к указателям. Если вызов выполняется через указатель на const, вызывается перегрузка const. В противном случае вызывается неконстантная перегрузка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...