Как стать автором
Обновить

Комментарии 88

Люблю мнемоническое правило: const — суффиксное определение. Определяет константность того, что идёт перед ним.
Вы меня запутали. Суффиксы обычно ставятся после слова, к которому они относятся.
А по делу это просто как в англиском языке прилагательное. 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;
Результаты плачевны… :( Спасибо за опрос, буду знать, что на этом полезно акцентировать.
Люблю писать так:

Foo const * const foo;

То есть, const стоит симметрично относительно «звездочки». Тогда сразу понятно, относится оно к самому типу, или к переменной-указателю.
А я напротив не люблю когда * или & висит в воздухе, всегда приклеиваю ее к правому слову, будь то const или имя переменной.

Очень полезно акцентировать, я очень люблю этот вопрос, как мне кажется — он как лакмусовая бумажка.
НЛО прилетело и опубликовало эту надпись здесь
Правильное мнемоническое правило — читать звёздочки и const с конца (опуская сам тип):
Foo * const -> переворачиваем и читаем -> константный указатель
const Foo * -> указатель на константу
const Foo * const -> константный указатель на константу
можно еще такой пример привести:
void *A::*B::*const* ptr1; — указатель на константный указатель на член B на указатель на член A
взял из книжки нижеупомянутой
Для таких примеров я слишком давно не писал на C++ :-D
НЛО прилетело и опубликовало эту надпись здесь
.еенжолс адук торобоан ьтасип, онжолс и жу кат ен отэ хывреп-оВ
Во-вторых, переставлять слова и буквы это совершенно разные вещи.
В-третьих, если вас не устраивает это мнемоническое правило — используйте любое другое, ничего не имею против.
А в четвёртых — вопрос о том, удобно сделан const или нет, вообще адресован не по адресу, обратитесь к Страуструпу ;-)
Только не к Страуструпу, а к Кернигану.
Пожалуй всё же к Страуструпу — const появился в C++ и только потом его добавили в стандарт C.
Про K&R C не уверен, но в C89 const уже был.
Автор, огласите правильный ответ!
Теперь все подглядывать будут :)
Если не ошибаюсь, то заглядывание под кат эквивалентно выбору «Воздержаться».
А я-то, баран, ответил неправильно: const Foo *foo. Давненько я const нигде не писал…
И это то же самое, что и Foo const* foo, не так ли? В сумме эти варианты всё-таки выигрывают, хотя и с трудом :)
Нет, это два разных типа.

Foo const* foo — объект типа Foo константный, а указатель можно изменять.

Foo *const foo — сам указатель изменять нельзя, а вот объект на который он указывает — можно.
не так.
Foo const *foo эквивалентен const Foo *foo
Однако, интуитивно! Угадал.
const Foo *foo — не может же большинство ошибаться! ;-)))
НЛО прилетело и опубликовало эту надпись здесь
Друзья, читайте книгу Стивена Дьюрхеста: Священные знания C++. Там эти случаи очень понятно обсуждаются. Судя по опросу народ этой темы не знает!
Да, очередной раз убеждаюсь. На хабре плюсов большинство не знает, хотя уверены, что знают.
Я не знаю плюсов и не утверждаю, что знаю. Честно говоря, мне даже не очень стыдно после таких топиков. Для тех приложений, которые я пишу и когда-либо писал, 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++ пока не прострелил себе неконстантным указателем колено.
С братом всё в порядке, я надеюсь?
Ггг… Я смотрю, в голосовании собрались знатоки C++… На самом деле не понимаю нытья вокруг сложности языка. Программирование — это инструмент специалиста. Если человек называет себя специалистом, пусть не ноет от профессиональных инструментов. Если нет, то пусть тем более не ноет от того что использует инструмент не по плечу. Это тоже самое что использовать проф инструмент Makita и жаловаться что слишком у него много настроек…
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
НЛО прилетело и опубликовало эту надпись здесь
А где можно посмотреть максимально полный список… кактусов?
НЛО прилетело и опубликовало эту надпись здесь
Что-то мне подсказывает, что это неполный список.
Вообще-то, относятся. Но проистекают из дизайна языка, и никуда от них не деться
Грустные результаты.
К 10% правильно ответивших можно добавить 40% справедливо воздержавшихся. Но таки грустно.
Результаты вполне ожидаемы. Особенно, когда запамятуешь, потом подумаешь и исправишься.
Результаты, впрочем, доказывают не всегда ясный синтаксис С/С++
НЛО прилетело и опубликовало эту надпись здесь
Хорошо, когда есть шанс исправиться и про вас не напишут как про фобос
Я думаю, что по для фобоса не за один день пишется, и не всегда сразу используются константные указатели на неконстантные объекты.
В конце концов, мы не знаем наверняка, ошибка ли это со стороны ПО. Есть только версия
Пойду расскажу людям про printf. :)
Чтобы проще ориентироваться в этом, лучше мысленно приписывать звездочку к типу, на который указатель указывает:
Черт, Ctrl-Enter.
const Foo* const ptr; — константный указатель на константный объект
const Foo* ptr; — указатель на константный объект
НЛО прилетело и опубликовало эту надпись здесь
То же самое что и const Foo* ptr.
перемещаем звездочку влево — часть, относящаяся к указателю, оказывается справа, а относящаяся к объекту — слева
Я ставлю звездочку к имени переменной, поскольку она означает, что именно эта переменная будет указателем.
Например,
int* a, b;
a — указатель, b — нет.
Ну да, я именно это и имел в виду. Тоже так пишу (с подачи уважаемого Джефа Элджера) :)
У нас такая конструкция запрещена по соглашению:

int* a, b; // запрещено, т.к. легко сделать ошибку

Мы пишем только так:

int* a;
int* b;

И по этому нет проблем с положением звездочки возле имени типа.
Что, на мое субъективное мнение, более естественно и удобочитаемо.

И, кстати, принятая у нас форма записи указателя на константу это:

const CFoo* fooPtr;
CFoo const* fooPtr; //мы так не пишем

А константные указатели мы не используем из-за ненадобности.
В результате очень удобно и все понятно.
Да уж, не ожидал увидеть такие результаты.
поискал по сурцам нашего проекта
55 использований
чрезвычайно мало
хз что это говорит о качестве нашего кода
но код этот принёс не один мильярд долларов нашей компании за 5 лет жизни

кстати, в том числе нашёл места где я это писал
ответил при этом я неправильно
хз что это говорит обо мне
Как-то на хабре писали про всякие мнемонические правила. Легче всего для меня спиральное:

Foo *const foo — Нам нужно узнать, что такое foo => идём влево от имени — константа
Далее по спирали направо через foo — там пусто, возвращаемся по спирали снизу к звездочке — указатель. Дальше аналогично: на пути спирила справа от foo — пусто, и мы попадаем на объект Foo.

Получаем константный указатель на объект.

Тоже самое и с функциями, только на добавляются слова «функция» и «возвращает».
Долго пытался понять сам вопрос.
К правильному ответу пришел следующим образом:
const Foo* == Foo const* — указатель на const Foo (используется очень часто),
а значит Foo * const — правильный ответ (редко используется).
Вопрос только в том, зачем оно надо?
Если для того, чтобы защититься от переопределения указателя внутри функции,
то в силу сложности определения типа такая защита сводится на нет.
Ну судя по проценту правильного ответа Голуба читали очень мало людей. Хотя я програмируя последний раз на С++ года два нащад всё таки вспомнил.
Да тут дело не в том кто что читал.
Просто эти конструкции со странностями сами по себе и долго удерживать в памяти все ньюансы языка трудно.
Я вот периодически забываю как объявлять указатель на функцию, но если мне надо, то в миг прочитаю и вспомню.
Не вижу смысла держать в памяти редкоиспользуемые конструкции языка.
Разве что перед собеседованием…
Мне интересно чем руководствовались люди, отвечая 1, 2, 3 или последним ответом.
Есть ресурс для чтения и конструирования таких и болеее навороченных конструкций.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории