Форум программистов, компьютерный форум, киберфорум
Наши страницы
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 4.60/5: Рейтинг темы: голосов - 5, средняя оценка - 4.60
igdev
74 / 63 / 27
Регистрация: 22.04.2016
Сообщений: 374
Завершенные тесты: 3
1

Возвращение неконстантного указателя из константного указателя на строку

19.08.2017, 22:14. Просмотров 858. Ответов 7
Метки нет (Все метки)

Не могу до конца понять один момент.
Допустим, у нас есть функция searchSymbol, которая принимает два параметра: константный указатель на строку и символ, который нужно найти в этой строке.
Функция выполняет следующие действия: находит заданный символ в строке и возвращает на него указатель в этой строке, в противном случаи - возвращает NULL.
C++
1
2
3
4
5
6
7
8
9
10
char *searchSymbol(const char *stringPtr, int symbol)
{
    while(*stringPtr != '\0')
    {
        if (*stringPtr == symbol)
            return stringPtr;
        stringPtr++;
    }
    return NULL;
}
Функция вызывается так:
C++
1
2
3
4
5
6
    char *ptr = searchSymbol("asdR", 's');
    
    if (ptr != NULL)
        std::cout << "Search symbol: " << ptr << std::endl;
    else
        std::cout << "Symbol not found" << std::endl;
Логично, что такой код компилятор не пропустит и выдаст ошибку о том, что функция searchSymbol возвращает не char *, a const char *.

Как можно возвратить char * не нарушая принцип наименьших привилегий относительно const char *stringPtr, т.к. нам stringPtr нужен только для поиска и мы его не собираемся изменять, т.е. stringPtr должен быть константным?
0
Лучшие ответы (1)
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
19.08.2017, 22:14
Ответы с готовыми решениями:

В чём отличие константного указателя и указателя на константу?
int *const p1 и int const* p2 Объясните мне в чём тут отличие.

Возвращение указателя на соответствующую строку
Доброго времени суток. Есть задача: по номеру дня недели вывести его название...

Возвращение указателя на начало первой строки
Программа отказывается выполнять второй цикл. #include &quot;stdafx.h&quot;...

Одновременная реализация константного и неконстантного оператора [] в классе string
Вобщем, проблема в следующем: нужно реализовать обращение по индексу в классе...

Возвращение функцией массива (или указателя на массив)
Вопрос опытным. Имеется массив картинок TImage, который создается одной...

7
anapshy
215 / 208 / 185
Регистрация: 14.11.2016
Сообщений: 817
Завершенные тесты: 3
19.08.2017, 22:58 2
igdev, возвращай так return const_cast<char*>(stringPtr);
1
MisterR
67 / 66 / 52
Регистрация: 28.10.2015
Сообщений: 386
Завершенные тесты: 3
19.08.2017, 23:03 3
C++
1
return const_cast<char*>(stringPtr);
1
DrOffset
9014 / 4861 / 1196
Регистрация: 30.01.2014
Сообщений: 7,942
19.08.2017, 23:43 4
Цитата Сообщение от igdev Посмотреть сообщение
Как можно возвратить char * не нарушая принцип наименьших привилегий относительно const char *stringPtr
А зачем это делать? В смысле, зачем возвращать указатель не на константу? Если ты соберешься менять данные по такому указателю, то получишь UB. Т.е. у нас выбор:
* да, мы хотим менять данные по возвращенному указателю, тогда принимать функция должна указатель не на константу.
* нет, мы не хотим менять данные по возвращенному указателю, тогда функция должна возвращать указатель на константу.
Третий вариант возможен, если, например, эта функция внутри себя будет делать копию переданной строки. Тогда да, можно распорядиться так, что возвращать указатель без const на эту копию.
1
igdev
74 / 63 / 27
Регистрация: 22.04.2016
Сообщений: 374
Завершенные тесты: 3
20.08.2017, 00:22  [ТС] 5
DrOffset,
Цитата Сообщение от DrOffset Посмотреть сообщение
А зачем это делать?
Решаю задачи по книге Х. Дейтел "Как программировать на С++". В одной из глав рассматривались функции из библиотеки <cstring>, а именно: strchr, strrchr, strspn, strbrk, strcspn, strstr.
Одним из заданий к главе было написать собственные реализации этих функций.
Я привел в данной теме пример собственной реализации функции: char *strchr(const char*s, int c)
Тогда почему функция из библиотеки <cstring> принимает константный указатель, а возвращает неконстантный? В чем суть данной проблемы?

Добавлено через 12 минут
Цитата Сообщение от DrOffset Посмотреть сообщение
Третий вариант возможен, если, например, эта функция внутри себя будет делать копию переданной строки. Тогда да, можно распорядиться так, что возвращать указатель без const на эту копию.
Т.е. получается, что функции из библиотеки <cstring> возвращают указатель на какую-то копию переданной строки?
0
DrOffset
9014 / 4861 / 1196
Регистрация: 30.01.2014
Сообщений: 7,942
20.08.2017, 02:12 6
Лучший ответ Сообщение было отмечено igdev как решение

Решение

Цитата Сообщение от igdev Посмотреть сообщение
Т.е. получается, что функции из библиотеки <cstring> возвращают указатель на какую-то копию переданной строки?
Нет, этот вывод сделан из неверной предпосылки, будто бы strchr принимает указатель на константу и возвращает при этом указатель на неконстанту, хотя это не так. Функция существует в двух перегруженных вариантах, принимающая и возвращающая указатель на неконстанту и принимающая и возвращающая указатель на константу. Это хорошо видно в документации, например здесь. Если в книге описание функции не соответствует документации, то это скорее всего опечатка.

Добавлено через 6 минут
А, я понял откуда там это. Такое объявление функция имеет в языке С. Действительно, никакой копии там не делается, а просто снимается константность. Это оставляет проблему с изменением константных данных на совести программиста. Т.е не смотря на неконстаность данных по возвращаемому указателю, программист не имеет права его использовать для изменения, если данные и в самом деле изначально были константными (иначе будет UB). В С так сделано не от хорошей жизни - ведь в С нет перегрузки, поэтому часть забот о const-корректности в этом случае переложена на программиста. Тем не менее, это неважно, т.к. мы находимся в разделе по С++. И здесь в силе то, о чем я писал выше.

Добавлено через 5 минут
Еще хочу добавить, что некоторые старые реализации библиотеки (сделанные еще до стандартизации) могли допускать такие ситуации - со снятием константности, делалось это финтами, наподобие приведенных выше с const_cast. Но на них не стоит равняться - это некорректный (или по крайней мере ошибкоопасный) код с точки зрения современного С++.

Добавлено через 2 минуты
Цитата Сообщение от igdev Посмотреть сообщение
Одним из заданий к главе было написать собственные реализации этих функций.
Если нужно это сделать, то правильным выбором будет поступить так же, как это сделано в стандартной библиотеке: предоставить константную и неконстантную версии этих функций. const-корректность одна из важнейших тем современного С++, поэтому не стоит ей пренебрегать даже на ранних этапах обучения.
1
igdev
74 / 63 / 27
Регистрация: 22.04.2016
Сообщений: 374
Завершенные тесты: 3
20.08.2017, 12:55  [ТС] 7
DrOffset,
Цитата Сообщение от DrOffset Посмотреть сообщение
const-корректность одна из важнейших тем современного С++, поэтому не стоит ей пренебрегать даже на ранних этапах обучения.
Можете поделится ссылкой на материалы, в которых подробно рассматривается данный вопрос?
0
DrOffset
9014 / 4861 / 1196
Регистрация: 30.01.2014
Сообщений: 7,942
20.08.2017, 13:56 8
Цитата Сообщение от igdev Посмотреть сообщение
Можете поделится ссылкой на материалы, в которых подробно рассматривается данный вопрос?
Эффективное использование С++ (55 советов), С.Мэйерс, правило 2, правило 3.
Стандарты программирования на С++, Г.Саттер, А.Александреску, правило 15, правило 94, правило 67
Решение сложных задач на С++, Г.Саттер, задача 10.3, задача 10.4
2
20.08.2017, 13:56
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
20.08.2017, 13:56

Почему увеличение указателя на sizeof(тип) не тождественно инкременту этого же указателя?
Всем доброго дня.:) Можете обьяснить ,почему при инкриментировании...

Создание указателя на экземпляр класса, описанного после объявления указателя
Здравствуйте! Проблема в том, что нужно сделать так: class A{ public: B*...

Возвращение ссылки или указателя на закрытый элемент класса.
Всех уважаемых форуман. поздравляю с наступившим новым годом и прошу ответить...


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

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.
Рейтинг@Mail.ru