Другая функция operator[], которую мы вызывали
Когда вы определяете два объекта, один из них является константным, а другой неконстантным, например:
const TextBlock a("Hello");
TextBlock b("World");
Когда вы используете a[0]
и b[0]
, будут вызываться разные типы operator[]
. Первый из них -- a[0]
будет вызывать функцию const:
const char &operator[](int) const;
Поскольку a
является константным объектом, каждая операция над ним не может изменить его значение. Поэтому, когда он использует оператор []
, будет вызвана версия const и вернет тип const char&
, что также означает, что мы не можем изменить значения ее членов.
С другой стороны, второй -- b[0]
вызовет неконстантную функцию:
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 &
здесь, тогда как в исходном операторе возврата есть явное преобразование.
Не забудьте добавить &
в первое выражение, которое означает, что мы используем ссылку на объект вместо реального объекта. Или он вызовет конструктор присваивания для создания нового объекта. Если это произойдет, tmp
не будет иметь ничего общего с *this
. Это разные объекты, даже если они имеют одинаковое значение. Что бы мы ни изменили в tmp, фактический объект, которым мы хотим управлять, не изменится!
person
WingCuengRay
schedule
20.01.2016