Sample_Program-1
#include<iostream>
using namespace std ;
int main(){
const int i = 9;
int *j = const_cast<int*>(&i); //Ok
int *j = const_cast<int*>(i); //Error
}
Sample_Program-2
#include<iostream>
using namespace std ;
int main(){
const int i = 9;
int j = const_cast<int&>(i);//Ok
int j = const_cast<int>(i);//Error
}
Я только изучал некоторую концепцию c ++ и встретился с двумя вышеупомянутыми концепциями. Кто-нибудь может, пожалуйста, объяснить концепцию, которую я пометил как ошибку в приведенном выше примере 2 программы?
1) Вы приводите (const int *) к (int *). Так что из-за модификатора const вы не можете изменить значение, которое помещается по этому адресу (указатель указывает на какой-то адрес в памяти). Когда вы приведете его к (int *), компилятор позволит изменять данные по этому адресу.
2) Вы пытаетесь привести (const int) к указателю на int (int *). (int) и (int *) — это разные типы. Это то же самое, что попросить const_cast привести строку в плавающее состояние. Оператор const_cast не может изменить тип переменной. Чтобы сделать такие вещи, вы должны смотреть на static_cast или reinterpret_cast.
3) Вы приводите const int для ссылки на int и присваиваете значение int (вы просто копируете значение в новую переменную). Это, вероятно, не совсем то, что вы хотели, потому что изменение j в этом случае не меняет i. Вы можете создать ссылку на int вместо j, а затем вы можете изменить значение i.
4) Я не понимаю, что вы пытаетесь сделать здесь. Идея const_cast состоит в том, чтобы удалить защиту const на объекте. Так что эта операция возможна только по указателям и ссылкам. Вам не нужно ничего приводить, чтобы скопировать const int в int. Но вы не можете изменить значение i, пока не возьмете указатель или ссылку и не снимите защиту.
Заключение. Удаление const — плохой стиль программирования. Предположим, вы написали библиотеку, в которой функция имеет аргумент const int *. Пользователь вашей библиотеки будет уверен, что его int не изменится, но вы изменили его, и он потерял нужные ему данные.
Когда ты пишешь
int *j = const_cast<int*>(i);
Вы пытаетесь преобразовать «я» в указатель. const_cast
не предназначен для использования для изменения типа данных.
может ты имел ввиду
int *j = const_cast<int*>(&i);
Вот первое объяснение объяснения:
[приведение к неконстантному указателю int] ([получить указатель на ‘i’ (const)]); const_cast<int*> ( &i );
Вот второе объяснение:
[приведение к неконстантному указателю int] ([получить значение ‘i’]); const_cast<int*> ( i );
Ошибка в том, что целочисленное значение не является значением указателя, и поэтому const_cast не может выполнить это приведение. Он может отображать только указатели на указатели или ссылки на ссылки.
Вот третье объяснение:
[приведение к неконстантной ссылке int] ([неявно получить ссылку на ‘i’ (const)]); const_cast< int& > ( i );
Вот второе объяснение:
[приведение к неконстантному значению int] ([получить значение ‘i’ (const)]); const_cast< int > ( i );
Ошибка в том, что const_cast нельзя использовать для приведения между значениями, только между указателями или ссылками. Для ценностей мы говорим о «конверсиях», а не о приведениях. Как в:
int i_nc = i;
// ОК: нет необходимости в const-cast, так как значение копируется.
Преобразование — это метод для копирования значения объекта одного типа в объект другого типа. Операторы приведения не имеют смысла для этой цели.