Явное приведение const_cast в С++

Желательно немного знать Шаблоны функций в С++ для начинающих Первое знакомство

Явное приведение типа const_cast — используют для того, чтобы отбросить квалификатор const у изначально не константных данных или добавить квалификатор const.

  • const_cast не влияет на оригинальную переменную: не убирает её const и не добавляет ей const

Отбрасывание квалификатора const у переменных, которые изначально живут с приписанным им квалификатором const, может привести к неопределённому поведению программы.

Вот один из забавных примеров, в котором, в зависимости от компилятора и его оптимизатора, две переменные могут попасть на один адрес, чего по сути быть не может, и, конечно, это только иллюзия, а не действительность. В любом случае в нижепоказанном коде идёт попытка снятия константности с изначально константным значением, что однозначно есть неопределённое поведение.

В данной ситуации const_cast снимает константность при преобразовании типа. Поскольку переменная i была изначально константной, её адрес имел тип const int*. Благодаря const_cast с типа адреса была снята константность, и его стало возможно поместить в переменную, на которую указывает b, где эта переменная есть не const целое число. Значение i на самом деле изменяется. То, что на экран выводится её предыдущее значение — результат некорректной работы оптимизатора, который ошибочно предположил, что объявленная как const переменная i изменяться не будет и подставил то значение, которое указано ещё при инициализации.

В любом случае — изменение переменной, которая инициализирована как const — это неопределённое поведение работы программы.

Возникает очень логичный вопрос, какой тогда смысл в использовании const_cast, ответ на этот вопрос на поверхности: иногда нужно изменять значение, которое изначально не квалифицировано как константное, но на каких-то этапах программы заболело свойством константности. Один из простых примеров:

Это опасный пример, потому что надо точно знать, что внутри функции foo указатель char не будет изменять того, на что указывает.

Вот ещё один пример. Этот пример UB.

В этом примере идёт попытка изменить константное значение pop2. Этот пример может сработать, но поведение программы из-за этого изменения не определено.

Если отбросить всё, что может нарушить целостность const переменных, то пример вполне рабочий, но опять же опасный, потому что какой-нибудь нехороший ломастер обязательно создаст указатель на константу, который отдаст функции, и в итоге будет неопределённое поведение программы.

Вот хороший пример, хотя в показываемом виде не практичный:

Некоторые люди считают, что const_cast только снимает константность, в действительности эта операция не только снимает константность, но и добавляет её, точнее с помощью неё можно добавить константность. Пример, показываемый мной ниже, из-за const скомпилирован не будет.

  • Операцию const_cast для сброса const следует использовать только тогда, когда точно знаешь, что делаешь, использовать её в своём коде равнозначно отмашке от компилятора: "Скройся! Я лучше тебя знаю, что нужно делать."

Поэтому лучше всего это приведение для сброса const не использовать никогда, только если выхода никакого нет и всё сто тысяч пятьсот раз хорошенько обдумано, только тогда её имеет смысл использовать для сброса на своё страх и риск, с осознанием того, что это очень и очень плохо.
В добавлении же константности ничего предосудительного нет. Константа — это хорошо.

  • Операция const_cast — это снятие константности или добавление константности при преобразовании типа.

При любом преобразовании переменная, которую приводят к какому-то типу, остаётся той переменной, какой она была. На основе оригинальной переменной создаётся временная переменная, тип для которой подхватывается из типа оригинальной переменной. Вот отбрасыванием const или добавлением const к типу временной переменной операция const_cast и занимается.

  • Операция const_cast позволяет выполнить приведение типа, только если значение объявлено как const или volatile.
  • const_cast возможно использовать, если тип, к которому выражение приводится, такой же, как у самого выражения, не учитывая квалификаторы const/volatile.

Т. е. типы внутри угловых скобок и внутри круглых должны быть одинаковыми, если устно отбросить квалификаторы const и volatile.

Все комментарии на сайте проверяются, поэтому ваш комментарий может появиться не сразу. Для вставки кода в комментарий используйте теги: [php]ВАШ_КОД[/php]

Добавить комментарий

Ваш e-mail не будет опубликован.

Поиск

 
     

Случайная книга в электронном формате

Яндекс.Метрика
НАГРАДИ АВТОРА САЙТА
WEBMONEY
R375024497470
U251140483387
Z301246203264
E149319127674

Демотиватор рекурсии

Выражаю свою признательность

  • Максиму очень признателен за указание на мои ошибки и неточности.
  • Sergio ===> за оказание помощи в исправлении моих ошибок
  • Gen ===> за правильное стремление помочь другим новичкам и выявления моих ошибок