Почему правильность константы характерна для C++?

См. мое сообщение здесь , Проблемы HDMI с Optimus решили , вероятно, что у Вас есть подобная проблема и что Ваше ТВ/монитор и его разрешения не определяются правильно.

40
задан Asik 2 September 2009 в 21:20
поделиться

9 ответов

Корректность констант дает два заметных преимущества C ++, о которых я могу думать, одно из которых делает его довольно уникальным.

  • Он позволяет широко распространить идеи изменяемых / неизменяемых данных, не требуя связки интерфейсов . Отдельные методы могут быть аннотированы относительно того, могут ли они выполняться на константных объектах, и компилятор обеспечивает это. Да, иногда это может быть проблемой, но если вы используете его последовательно и не используете const_cast , у вас есть проверенная компилятором безопасность в отношении изменяемых и неизменяемых данных.
  • Если объект или данные это const , компилятор может поместить его в постоянную память. Это особенно важно для встроенных систем. C ++ поддерживает это; немногие другие языки делают. Это также означает, что в общем случае вы не можете безопасно отбросить const , хотя на практике вы можете сделать это в большинстве сред.

C ++ - не единственный язык с константной корректностью или чем-то подобным. OCaml и Standard ML имеют схожую концепцию с разной терминологией - почти все данные неизменяемы (const), и когда вы хотите, чтобы что-то было изменяемым, вы используете другой тип (тип ref ) для этого. Так что это просто уникально для C ++ в пределах его соседних языков.

Наконец, обратное направление: были времена, когда я хотел const в Java. final иногда не заходит так далеко, чтобы создать просто неизменяемые данные (особенно неизменяемые представления изменяемых данных), и не хочет создавать интерфейсы.

63
ответ дан 27 November 2019 в 01:01
поделиться

Ключевое слово const в C ++ (применительно к параметрам и объявлениям типов) - это попытка удержать программистов от того, чтобы они не выскакивали из головы и не вырывали при этом всю ногу.

основная идея - обозначить что-либо как «не может быть изменено». Тип const нельзя изменить (по умолчанию). Константный указатель не может указывать на новое место в памяти. Просто, не так ли?

Что ж, вот где пригодится корректность const. Вот некоторые из возможных комбинаций, в которых вы можете оказаться при использовании const:

Константа переменная Подразумевает, что данные, помеченные именем переменной, не могут быть изменены.

Указатель на константную переменную Подразумевается, что указатель может быть изменен, но сами данные - нет.

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

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

Вы видите, что там некоторые вещи могут быть глупыми? Вот почему, когда вы используете const, важно правильно указать, какую const вы маркируете.

Дело в том, что это всего лишь хакерство во время компиляции. Маркировка просто сообщает компилятору, как интерпретировать инструкции. Если вы откажетесь от const, вы сможете делать все, что захотите. Но вам все равно придется вызывать методы, у которых есть константные требования, с соответствующими типами.

1
ответ дан 27 November 2019 в 01:01
поделиться

В C, Java и C # вы можете определить, посмотрев на сайт вызова, может ли переданный объект быть изменен функцией:

  • в Java вы точно знаете, что это возможно.
  • ] в C вы знаете, что это может быть только при наличии символа «&» или его эквивалента.
  • в C # вам также нужно сказать «ref» на сайте вызова.

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

Это может существенно повлиять на читаемость любого кода, вызывающего функции. Этого, вероятно, достаточно, чтобы оправдать наличие языковой особенности.

2
ответ дан 27 November 2019 в 01:01
поделиться

Вы также хотите использовать константу в методах, чтобы воспользоваться преимуществами оптимизации возвращаемого значения. См. Пункт 20. «Более эффективный C ++ Скотта Мейерса».

4
ответ дан 27 November 2019 в 01:01
поделиться

Вы правы , const-корректность не нужна. Вы, конечно, можете написать весь свой код без ключевого слова const и заставить все работать, как в Java и Python.

Но если вы сделаете это, вы больше не получите помощи компилятора в проверке нарушений const. Ошибки, о которых компилятор мог бы сообщить вам во время компиляции, теперь будут обнаруживаться только во время выполнения, если они будут обнаружены вообще, и, следовательно, вам потребуется больше времени для диагностики и исправления.

Таким образом, попытки подорвать или избежать использования const - функция правильности только усложняет вам задачу в долгосрочной перспективе.

13
ответ дан 27 November 2019 в 01:01
поделиться

Программирование - это запись на языке, который в конечном итоге будет обрабатываться компьютером, но это одновременно способ общения с компьютером и другими программистами в одном проекте. Когда вы используете язык, вы ограничены концепциями, которые могут быть выражены в нем, а const - это всего лишь еще одно понятие, которое вы можете использовать для описания вашей проблемы и вашего решения.

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

Язык и мышление тесно связаны. Вы можете выражать свои мысли только на том языке, на котором говорите, но язык также меняет то, как вы думаете. Тот факт, что у вас не было ключевого слова const в языках, с которыми вы работали, означает, что вы уже нашли другие решения тех же проблем, и эти решения кажутся вам естественными.

В вопросе вы утверждали, что можете предоставляют неизменяемый интерфейс, который может использоваться функциями, которым не нужно изменять содержимое объектов. Если вы задумаетесь на секунду, то это же предложение говорит вам, почему const - это концепция, с которой вы хотите работать. Необходимость определить неизменяемый интерфейс и реализовать его в своем классе - это работа, связанная с тем фактом, что вы не можете выразить эту концепцию на своем языке.

Постоянство позволяет вам выразить эти концепции на языке, который компилятор (и другие программисты ) можно понять. Вы устанавливаете компромисс в отношении того, что вы будете делать с параметрами, которые вы получаете, ссылками, которые вы храните, или определяете ограничения на то, что пользователям вашего класса разрешено делать с предоставленными вами ссылками. Практически каждый нетривиальный класс может иметь состояние, представленное атрибутами, и во многих случаях есть инварианты, которые необходимо сохранить. Язык позволяет вам определять функции, которые предлагают доступ к некоторым внутренним данным, и в то же время ограничивает доступ только для чтения, что гарантирует, что никакой внешний код не нарушит ваши инварианты.

Это концепция, по которой мне больше не хватает при переходе на другие языки. Рассмотрим сценарий, в котором у вас есть класс C, который, среди прочего, имеет атрибут a типа A, который должен быть видимым для внешнего кода (пользователи вашего класса должны иметь возможность запрашивать некоторую информацию о a). Если тип A имеет какую-либо операцию изменения, то, чтобы пользовательский код не менял ваше внутреннее состояние, вы должны создать копию a и вернуть ее. Программист класса должен знать, что необходимо выполнить копирование, и должен выполнить (возможно, дорогое) копирование. С другой стороны, если бы вы могли выразить постоянство в языке, вы могли бы просто вернуть постоянную ссылку на объект (фактически ссылку на постоянное представление объекта) и просто вернуть внутренний элемент. Это позволит пользовательскому коду вызывать любой метод объекта, который отмечен как неизменяемый, таким образом сохраняя инварианты вашего класса.

Проблема / преимущество, все зависит от точки зрения, постоянства в том, что она вирусна. Когда вы предлагаете постоянную ссылку на объект, могут быть вызваны только те методы, которые помечены как не изменяющиеся, и вы должны сообщить компилятору, какой из методов имеет это свойство. Когда вы объявляете константу метода, вы сообщаете компилятору, что пользовательский код, вызывающий этот метод, сохранит состояние объекта. Когда вы определяете (реализуете) метод, имеющий постоянную сигнатуру, компилятор напомнит вам о вашем обещании и фактически потребует, чтобы вы не изменяли данные внутри себя.

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

В этом контексте никогда не следует использовать const_cast <>, поскольку результаты могут привести вас в область неопределенного поведения (как из с точки зрения языка: объект может находиться в постоянной памяти, а с точки зрения программы: вы можете нарушать инварианты в других классах). Но это, конечно, вы уже знаете, если читаете C ++ FAQ lite.

В качестве примечания, последнее ключевое слово в Java не имеет ничего общего с ключевым словом const в C ++, когда вы имеете дело со ссылками ( в ссылках или указателях C ++). Ключевое слово final изменяет локальную переменную, на которую оно ссылается, будь то базовый тип или ссылка, но не является модификатором указанного объекта. То есть, вы можете вызывать изменяющие методы через последнюю ссылку и, таким образом, обеспечивать изменения состояния указанного объекта. В C ++ ссылки всегда постоянны (вы можете привязать их к объекту / переменной только во время построения), а ключевое слово const изменяет способ взаимодействия пользовательского кода с указанным объектом. (В случае указателей вы можете использовать ключевое слово const как для данных, так и для указателя: X const * const объявляет постоянный указатель на константу X )

8
ответ дан 27 November 2019 в 01:01
поделиться

Я не думаю, что кто-то утверждает, что корректность const «необходима». Но опять же, классы тоже не нужны, не так ли? То же самое касается пространств имен, исключений, ... вы понимаете.

Константа-корректность помогает обнаруживать ошибки во время компиляции, и поэтому она полезна.

30
ответ дан 27 November 2019 в 01:01
поделиться

const - это способ выразить что-то. Было бы полезно на любом языке, если бы вы считали важным выразить это. У них нет этой функции, потому что разработчики языка не сочли их полезными. Я думаю, что если бы эта функция была там, она была бы столь же полезной.

Я думаю, что это как спецификации throw в Java. Если они вам нравятся, вы, вероятно, захотите их на других языках. Но разработчики других языков не думали, что это так важно.

16
ответ дан 27 November 2019 в 01:01
поделиться

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

6
ответ дан 27 November 2019 в 01:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: