Другая функция оператора [], которую мы назвали
Когда вы определяете два объекта, один является постоянным, а другой неконстантным, как это:
const TextBlock a("Hello");
TextBlock b("World");
Когда вы используете a[0]
иb[0]
, будет вызван другой тип operator[]
. Первый - a[0]
, вызовет функцию const :
const char &operator[](int) const;
Поскольку a
является const-объектом, каждая операция над ним не может изменить свое значение.Поэтому, когда он использует оператор []
, вызывается версия const и возвращается тип const char&
, что также означает, что мы не можем изменять значения его членов.
С другой стороны,второй - b[0]
вызовет функцию non-const :
char &operator[](int);
Объект может быть изменен, также как и его член.Таким образом, эта функция возвращает тип char &
, который можно изменить.
Что делается в неконстантной функции?
Итак, давайте посмотрим на связь между неконстантной функцией ипостоянная функция.В вашей программе неконстантная функция реализуется путем вызова константной функции.
Обычно неконстантный объект не может напрямую вызывать константную функцию.Но мы можем изменить атрибут на static_cast<>
.Таким образом, мы можем преобразовать объект b
в const TextBlock
, чтобы он мог вызывать функцию const.
Мы делаем это в char &operator[](int index)
, что может уменьшить повторное использование кода.
char & operator[](int position)
{
// const TextBlock tmp = *this;
// return const_cast<char &>(tmp[position]);
return
const_cast<char &>( (static_cast<const TextBlock &>(*this))[position] );
}
При использовании static_cast<const TextBlock &>(*this)
он неявно определяет временный объект, который является преобразованием TextBlock &
в const TextBlock &
в *this
.
После преобразования у нас есть временный объект, и мы назвали его tmp .Таким образом, мы можем использовать tmp[0]
для вызова функции const, что мы и делаем.
После возврата из функции const мы получаем значение, тип которого равен const char &
.Но мы на самом деле хотим это char &
.Поэтому мы используем const_cast<char &>
удалить атрибут const из возвращаемого значения.После этого мы получаем неконстантную ссылку в char, значения которой мы можем изменить.
На самом деле оператор return в неконстантной функции можно заменить следующим образом:
const TextBlcok &tmp = *this;
return const_cast<char &>tmp[position];
tmp
- это временная ссылка на * this (не временный объект).У нас есть неявное преобразование из TextBlock &
в const TextBlock &
здесь, тогда как в исходном операторе return явно есть преобразование.
Не забудьте добавить &
в первый оператор , что означает, что мы используем ссылку на объект вместо реального объекта.Или он вызовет конструктор присваивания для генерации нового объекта.Если это произойдет, tmp
не будет иметь ничего общего с *this
.Это разные объекты, даже если они имеют одинаковое значение.Что бы мы ни изменяли в tmp, реальный объект, которым мы хотим управлять, не изменится!