Вы меня запутали. Суффиксы обычно ставятся после слова, к которому они относятся.
А по делу это просто как в англиском языке прилагательное. A constant variable = const var.
Я к тому, что int* указатель на int, int const* — указатель на константу, int* const — константный указатель, int const * const — константный указатель на константу. Для меня const ближе как прилагательное во французском.
Я const пишу перед определение типа, мне так легче понимать и запомнить (да, я знаю, что разницы нет, но всё же).
Определение разбивается звездочкой * на две половинки:
данные * указатель;
Данные это char, int, float и др. Указатель это имя p, ptr или какое-нибудь другое.
Возмём обычный указатель на целое:
int * p;
Теперь если у нас данные константы, то нужно добавить const перед данными (как прилагательное):
const int * p; // указатель на константу
Если же сам указатель константный нужен, то ставим const перед ним:
int * const p; // константный указатель на переменную
И вариант когда и данные, и указатель константы:
const int * const p; // константный указатель на константу
Шаблон:
(const) data * (const) pointer;
A (constant) data pointed by a (constant) pointer;
Тогда задание будет таким:
An integer pointed by a constant pointer ptr;
int * const ptr;
Правильное мнемоническое правило — читать звёздочки и const с конца (опуская сам тип):
Foo * const -> переворачиваем и читаем -> константный указатель
const Foo * -> указатель на константу
const Foo * const -> константный указатель на константу
можно еще такой пример привести: void *A::*B::*const* ptr1; — указатель на константный указатель на член B на указатель на член A
взял из книжки нижеупомянутой
.еенжолс адук торобоан ьтасип, онжолс и жу кат ен отэ хывреп-оВ
Во-вторых, переставлять слова и буквы это совершенно разные вещи.
В-третьих, если вас не устраивает это мнемоническое правило — используйте любое другое, ничего не имею против.
А в четвёртых — вопрос о том, удобно сделан const или нет, вообще адресован не по адресу, обратитесь к Страуструпу ;-)
Я не знаю плюсов и не утверждаю, что знаю. Честно говоря, мне даже не очень стыдно после таких топиков. Для тех приложений, которые я пишу и когда-либо писал, C++ неоправданно сложен. А вообще, знатоки С++ для меня всегда были какой-то особенной, крутой, кастой.
Последний промышленный код на С++ пол года назад, несложное пользовательское действие на WinAPI для MSI, до того ещё два года не писал вообще ничего, ответил правильно хотя и не сразу.
С++ остался уделом для значительно меньшего круга задач чем 10 лет назад. Количество неправильных ответов думаю больше свидетельствует о недостаточно интуитивном синтаксисе для указателей, не думаю что из 1500+ ответивших более половины программисты на С/С++. Для многих на хабре С++ ассоциируется больше Алёной С++, а не Страуструпом, Александреску, Дьюхерстом, Голубом и т. д.
Этот вопрос подходит и для Си, если не смотреть на ответы с ссылкой. Такое хорошо разбиралось в Дейтел и Дейтел «Как программировать на C», с тех пор и запомнил.
Константы конечно надо знать, хотя я и сам неправильно ответил, каюсь.
Только вот мне одному кажется, что знание каких-то специфических сведений о языке является не очень полезным в повседневной жизни? Это как умение собирать автомат Калашникова за 8 секунд, вроде как круто, вроде как потенциально полезно, а по факту никому не надо.
Вот кто-то чуть выше написал, что знатоки С++ для него являются особенной кастой, а как по мне, так они только вред приносят, когда используют какие-то необычные и неоднозначные конструкции, а кто-то менее опытный потом ошибается при поддержке кода и тратит много времени на это. Но это так, IMHO.
в плюсах есть много тайных мест, использование которых действительно может быть overhead для дальнейшей поддержки кода другими людьми. Но такие вещи как конст — азы и знать их надо всем
плюс любой человек, пишущий на Qt и использующий PIMPL их тоже неявно использует, тамошние макросы Q_D и Q_Q как раз конст указатели на неконст объект возвращают. Как раз очень яркий пример использования (я кстати использовал для тех же целей у себя в коде, qt-шные макросы не очень подошли, пришлось писать свою реализацию)
Ну так человек, который пользуется Q_D и Q_Q может никогда и не задумываться о том, что же за ними скрывается. Иначе можно сказать, что любой человек, который использует компьютер с х86 архитектурой должен знать все детали этой архитектуры.
Вот когда оказалось, что почему-то не подходят стандартные конструкции, тогда можно и разобрать и сделать свое, как в Вашем случае, а держать в голове все детали всех используемых инструментов бессмысленно.
Ну так неявно мы в этой жизни столько всего используем…
Но я не спорю, надо было уточнить вопрос и добавить явно/осмысленно. Хотя Ваш случай в любом случае под него подходит.
Эм, это не специфическое знание. Константность это такая же возможность языка, как и не знаю, классы или функции. Вы же не смотрите в интернете как функцию объявить в любимом языке?
Я понимаю, что вы пытаетесь сказать, но нет, константность это не шаблоны и не виртуальное наследование — это не магия, это основные знания.
Я не спорю, что знать надо, я даже не утверждаю, что не знаю, но мое личное мнение и идеология, если можно так выразиться: все должно быть просто и чем проще тем лучше.
Речь шла о бусте и александреску как раз. Впрочем, это очень притяная магия. А если еще и метапрограммирование на препроцессоре добавить через BOOST.PREPROCESSOR — ммм, сказка.
Ну буквально постоянно. Когда объект изменяется, а укзатель нет. Я всегда всему проставляю const по максимуму — пусть компилятор ошибки проверяет на статике, а не говно на рантайме вылеает.
Вы — молодец, раз так делаете. (без шуток и иронии)
А мне лично как-то особо не попадались ситуации, когда это полезно. Так что все это дело опыта каждого отдельного человека.
Вот почему-то никто не замечает первого предложения, где прямо сказано, что константы надо знать.
Как по мне, так некоторые вещи могут пригодиться, а некоторые нет. Если Вы пользуетесь константами часто и они упрощают жизнь, то это замечательно. А мой личный опыт состоит в том, что время, затраченное на написание констант и последующего их удаления при изменении кода не стоит того времени, которое я сэкономил с ними при отладке. Может архитектура такая, что не надо мне попадается, может просто так везет, но вот такой вот факт.
Указатели это ядро языка. Для embedded или той же разработки игр вы не стоите ничего как разработчик плавая с указателями, потому что это то что у вас будет в коде через каждую строчку.
Ггг… Я смотрю, в голосовании собрались знатоки C++… На самом деле не понимаю нытья вокруг сложности языка. Программирование — это инструмент специалиста. Если человек называет себя специалистом, пусть не ноет от профессиональных инструментов. Если нет, то пусть тем более не ноет от того что использует инструмент не по плечу. Это тоже самое что использовать проф инструмент Makita и жаловаться что слишком у него много настроек…
Результаты вполне ожидаемы. Особенно, когда запамятуешь, потом подумаешь и исправишься.
Результаты, впрочем, доказывают не всегда ясный синтаксис С/С++
Я думаю, что по для фобоса не за один день пишется, и не всегда сразу используются константные указатели на неконстантные объекты.
В конце концов, мы не знаем наверняка, ошибка ли это со стороны ПО. Есть только версия
Я ставлю звездочку к имени переменной, поскольку она означает, что именно эта переменная будет указателем.
Например, int* a, b;
a — указатель, b — нет.
поискал по сурцам нашего проекта
55 использований
чрезвычайно мало
хз что это говорит о качестве нашего кода
но код этот принёс не один мильярд долларов нашей компании за 5 лет жизни
кстати, в том числе нашёл места где я это писал
ответил при этом я неправильно
хз что это говорит обо мне
Как-то на хабре писали про всякие мнемонические правила. Легче всего для меня спиральное:
Foo *const foo — Нам нужно узнать, что такое foo => идём влево от имени — константа
Далее по спирали направо через foo — там пусто, возвращаемся по спирали снизу к звездочке — указатель. Дальше аналогично: на пути спирила справа от foo — пусто, и мы попадаем на объектFoo.
Получаем константный указатель на объект.
Тоже самое и с функциями, только на добавляются слова «функция» и «возвращает».
Долго пытался понять сам вопрос.
К правильному ответу пришел следующим образом:
const Foo* == Foo const* — указатель на const Foo (используется очень часто),
а значит Foo * const — правильный ответ (редко используется).
Вопрос только в том, зачем оно надо?
Если для того, чтобы защититься от переопределения указателя внутри функции,
то в силу сложности определения типа такая защита сводится на нет.
Да тут дело не в том кто что читал.
Просто эти конструкции со странностями сами по себе и долго удерживать в памяти все ньюансы языка трудно.
Я вот периодически забываю как объявлять указатель на функцию, но если мне надо, то в миг прочитаю и вспомню.
Не вижу смысла держать в памяти редкоиспользуемые конструкции языка.
Разве что перед собеседованием…
Константный указатель на неконстантный объект это: