использование const_cast для передачи константного аргумента данных функции, параметр которой не является константным [дубликатом]

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

int fun(int* ptr)
{
    return (*ptr + 10);
}
int main(void)
{
    int val = 10;
    const int *ptr = &val;
    int *ptr1 = const_cast <int *>(ptr);
    cout << fun(ptr1);
    return 0;
}
Output:
20

Но мы также можем добиться приведения следующим образом:

int fun(int* ptr)
{
    return (*ptr + 10);
}
int main(void)
{
    int val = 10;
    const int *ptr = &val;
    int *ptr1 = (int *)ptr;
    cout << fun(ptr1);
    return 0;
}

Выход: 20

Тогда какая необходимость в использовании const_cast в этом конкретном сценарии? Есть ли преимущество использования const_cast только в этом конкретном сценарии?


person user1099327    schedule 30.01.2014    source источник
comment
Помимо ясности и безопасности кода есть еще одно преимущество: его можно найти. Намного сложнее найти все места, где кто-то отбрасывает константность, используя приведения в стиле C.   -  person molbdnilo    schedule 30.01.2014
comment
(int*) в этом случае совпадает с const_cast<int*>.   -  person Simple    schedule 30.01.2014


Ответы (2)


arrow_upward
3
arrow_downward

Потому что, когда вы указываете const_cast, вы явно указываете, что хотите удалить константность, в то время как приведение в старом стиле позволяет вам приводить что угодно к чему угодно. См. https://www.securecoding.cert.org/confluence/display/cplusplus/EXP05-CPP.+Do+not+use+C-style+casts

person user3159253    schedule 30.01.2014
comment
не могу получить доступ к указанной ссылке - person user1099327; 30.01.2014
comment
Ну, - поверь мне, - персонаж Арнольда Шварценеггера в фильме "Коммандос". На самом деле приведения в стиле C++ были введены в качестве замены старых приведения в стиле C. Как упоминалось выше, они более явные, их легко найти по всему коду, они буквально бросаются в глаза рецензенту и т. д. Если у вас нет явных причин использовать приведения в старом стиле, лучше их избегать, потому что они могут скрыть множество ошибок программирования и потенциально опасные операции. - person user3159253; 30.01.2014

arrow_upward
0
arrow_downward

Злой актерский состав в стиле C сделает практически любое преобразование, которое отдаленно возможно. Используя это, вы теряете всякую надежду на то, что система типов отловит ошибки в вашем коде.

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

Например, это приведение будет скомпилировано, но даст какое-то неопределенное поведение, если вы попытаетесь использовать указатель:

double * bad = (double*)ptr;

в то время как это приведение не сможет скомпилироваться, так как const_cast не может выполнять преобразования типов:

double * less_bad = const_cast<double*>(ptr);

Приведения работают (более или менее) следующим образом:

  • static_cast позволяет отменить «безопасные» преобразования; например, преобразование указателя на базовый класс в указатель на производный класс или void* в типизированный указатель. Он не допускает преобразований, которые не имеют смысла в системе типов.
  • reinterpret_cast допускает более сложные преобразования, такие как преобразование указателей в целые числа или несвязанные типы указателей. Используйте его с осторожностью, если вам нужно отказаться от системы типов, чтобы сделать что-то необычное.
  • const_cast позволяет удалить квалификаторы const и volatile, но не разрешает преобразование типов.
  • dynamic_cast позволяет выполнять преобразование между указателями или ссылками на полиморфные типы с проверкой во время выполнения, что преобразование допустимо. Это единственное «безопасное» приведение, так как оно не может дать неверно напечатанный результат.
  • Злой состав C позволяет все, что могут делать static_cast, reinterpret_cast и const_cast, и даже больше. Синтаксис трудно обнаружить или найти, поэтому используйте его, если хотите скрыть истинный ужас своего кода и довести до безумия программистов, обслуживающих его.
person Mike Seymour    schedule 30.01.2014