Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
#1

Const_cast - правильно ли я его использую? - C++

05.06.2014, 23:44. Просмотров 556. Ответов 11
Метки нет (Все метки)

Доброго времени суток!
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <string>
#include <iostream>
#include <typeinfo>
 
using namespace std;
 
int main()
{
    cout << string::npos << endl;
    cout << typeid(string::npos).name() << endl;
    long unsigned int* service = const_cast<long unsigned int*>(&string::npos);
    *service = 1000;
    cout << *service << ;
    return 0;
}
Его нужно использовать когда требуется изменить константу? Или как?
Почему не получается тогда поменять string::npos?
Вывод программы:
18446744073709551615
m
1000, 18446744073709551615

P.S. Что за тип такой - "m" ?

Добавлено через 34 минуты
В 13-й строчке:
C++
1
cout << *service << ", " << string::npos << endl;
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.06.2014, 23:44     Const_cast - правильно ли я его использую?
Посмотрите здесь:

Считать одномерный массив с файла, отсортировать его использую рекурсивный вызов функции C++
const_cast C++
C++ const_cast что это?
C++ const_cast: const и volatile
C++ const_cast mutable
C++ Не понятно с const_cast
const_cast(*this) C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Croessmah
Модератор
Эксперт CЭксперт С++
12702 / 7176 / 801
Регистрация: 27.09.2012
Сообщений: 17,701
Записей в блоге: 2
Завершенные тесты: 1
05.06.2014, 23:45     Const_cast - правильно ли я его использую? #2
Цитата Сообщение от andrejap Посмотреть сообщение
Его нужно использовать когда требуется изменить константу?
чтобы снять признак константности, именно признак.
В данном случае Ваше приложение уже не корректно.
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
05.06.2014, 23:55  [ТС]     Const_cast - правильно ли я его использую? #3
Croessmah,
Цитата Сообщение от Croessmah Посмотреть сообщение
чтобы снять признак константности
А чем это может помочь?
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
07.06.2014, 17:44  [ТС]     Const_cast - правильно ли я его использую? #4
А вот еще вопрос:
если есть функция
C++
1
2
3
4
5
void Enrollee::SetChoices(const int* c_ptr)
{
   int* ptr = c_ptr*;
   // ...
}
и компилятор говорит об ошибке: Enrollee.cpp:59:16: error: invalid conversion from ‘const int*’ to ‘int*’ [-fpermissive]
int* ptr = c_ptr;


А вот в случае:
C++
1
int* ptr = const_cast<int*>(c_ptr);
все нормально.

Правильно ли так использовать приведение типов?
0x10
2452 / 1624 / 238
Регистрация: 24.11.2012
Сообщений: 3,999
07.06.2014, 17:57     Const_cast - правильно ли я его использую? #5
Цитата Сообщение от andrejap Посмотреть сообщение
Правильно ли так использовать приведение типов?
Вы, собственно, чего добиться хотите? Сначала гарантируете, что данные константны, потом снимаете это ограничение. Выстрел в ногу.
Jupiter
Каратель
Эксперт C++
6549 / 3969 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
07.06.2014, 18:02     Const_cast - правильно ли я его использую? #6
Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от andrejap Посмотреть сообщение
Правильно ли так использовать приведение типов?
зависит от фактического аргумента функции при вызове. в случае case1 неправильно
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <iostream>
 
void foo(const int* cptr)
{
    int* ptr = const_cast<int*>(cptr);
    *ptr = 33;
}
 
void case1()
{
    const int n = 42;
    const int* cptr = &n;
    foo(cptr);
    std::cout << *cptr << '\n';
}
 
void case2()
{
    int n = 42;
    foo(&n);
    std::cout << n << '\n';
}
 
int main()
{
    case1();
    case2();
    return 0;
}
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
07.06.2014, 18:15  [ТС]     Const_cast - правильно ли я его использую? #7
0x10, Вы правы. Я почему то думал, что это считается плохим тоном, если указатель-параметр сразу и модифицировать, например:
C++
1
2
3
4
void function0(int* pointer)
{
   function1(pointer++);
}
Это ведь не так?

Jupiter, для const_cast аргумент должен быть const? И именно const int* (или const int* const), а не int* const ?
Jupiter
Каратель
Эксперт C++
6549 / 3969 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
07.06.2014, 18:28     Const_cast - правильно ли я его использую? #8
Сообщение было отмечено автором темы, экспертом или модератором как ответ
andrejap, вам уже писали про const_cast
Цитата Сообщение от andrejap Посмотреть сообщение
Его нужно использовать когда требуется изменить константу?
Цитата Сообщение от Croessmah Посмотреть сообщение
чтобы снять признак константности, именно признак.
в этой строке
Цитата Сообщение от Jupiter Посмотреть сообщение
C++
1
void foo(const int* cptr)
cptr это указатель на константу, это значит что сам указатель можно менять как угодно, но данные по этому указателю менять нельзя так как есть признак константности, при этом этот указатель может действительно указывать на константу (case1), а может указывать и не на константу (case2).
так вот в случае case2 мы вполне законно имеем право применять const_cast,
а в случае case2 по стандарту имеем undefined behaviour
Nick Alte
Эксперт С++
1603 / 995 / 118
Регистрация: 27.09.2009
Сообщений: 1,918
Завершенные тесты: 1
07.06.2014, 18:36     Const_cast - правильно ли я его использую? #9
Цитата Сообщение от andrejap Посмотреть сообщение
Его нужно использовать когда требуется изменить константу?
Ни в коем случае. Принудительное изменение константы - undefined behavior.
Такой тип приведения используется в случаях, когда надо "договориться" с компилятором на время "приподнять" ограничения, если намерения остаются честными: то есть, помеченные как const данные всё равно не будут изменяться или если право их изменять было изначально, но оказалось потеряно из-за применения const-операции.

Пример ситуации 1: мы используем стороннюю библиотеку на языке Си, в которой есть функция хитрой обработки строк. Из-за своего "пролетарского" происхождения аргумент функции описан как char*, а не const char*, однако авторы функции клятвенно обещают нам, что исходная строка не изменяется. При использовании такой функции из C++ с нормальных параметров-строк придётся принудительно снимать признак const, однако по факту данные не изменяются.

Пример ситуации 2: мы пишем свой контейнер для типа T с поиском элементов, реализованным через оператор []. Мы написали const-версию оператора, возвращающую ссылку const T&. Благодаря этому через const-версию контейнера нельзя изменять его элементы. Теперь мы хотим написать неконстантную версию, которая в общем делает всё то же самое, но разрешает изменять элементы. Дублировать функцию - мартышкин труд, и в случае изменений в алгоритме придётся распространять их уже на две функции. Так что лучше воспользуемся результатом работы const-версии оператора и снимем этого результата константность через const_cast.
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
07.06.2014, 18:49  [ТС]     Const_cast - правильно ли я его использую? #10
Ааа, понял! Grand merci, господа!

Добавлено через 11 минут
Nick Alte, а можно случай 2 по-подробнее. Синтаксис еще не разобрал:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Class0 {
public:
    int x[10];
    const int& operator[](int n)
    {
        return x[n];
    }
};
 
 
int main() {
Class0 obj;
//...
}
а потом как?
obj.x[9] = const_cast<int>(300); //бред у меня получается, как здесь оформить?
Nick Alte
Эксперт С++
1603 / 995 / 118
Регистрация: 27.09.2009
Сообщений: 1,918
Завершенные тесты: 1
07.06.2014, 18:55     Const_cast - правильно ли я его использую? #11
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Class0 {
public:
 
    const int& operator[] (int n) const  // Второй const показывает, что операция применима к const Class0
    {
        return x[n];
    }
 
    int& operator [] (int n)  // А вот это на const Class0 уже не сработает
    {
        return const_cast<int&>(  // Снимаем const со ссылки (было const int&, стало int&)
            const_cast<const Class0*>(this)->operator[](n)  // А здесь наоборот, навешиваем const на this,
            //чтобы вызвать предыдущий оператор
        );
    }
private:
    int x[10];
};
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
07.06.2014, 19:01     Const_cast - правильно ли я его использую?
Еще ссылки по теме:

О том, почему нелюбим goto; как его правильно использовать; и чем в моем случае его можно заменить? C++
Особенности использования const_cast C++
C++ Const_cast ub
C++ Const_cast и mutable
C++ Const_cast может добавлять константность?

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
andrejap
13 / 13 / 1
Регистрация: 21.04.2013
Сообщений: 245
07.06.2014, 19:01  [ТС]     Const_cast - правильно ли я его использую? #12
Ну красота, спасибо!
Yandex
Объявления
07.06.2014, 19:01     Const_cast - правильно ли я его использую?
Ответ Создать тему
Опции темы

Текущее время: 03:14. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru