Как правильность const помогает писать лучшие программы? - PullRequest
2 голосов
/ 13 апреля 2009

Этот вопрос от парня из C #, который спрашивает людей из C ++. (Я немного знаю C, но немного разбираюсь в C ++).

Многие разработчики на C ++, которые приходят на C #, говорят, что им не хватает правильности, что мне кажется довольно странным. В .Net, чтобы запретить изменение вещей, вам нужно создавать неизменяемые объекты или объекты со свойствами / полями только для чтения или передавать копии объектов (по умолчанию копируются структуры).

Является ли константность C ++ правильностью, механизмом создания неизменяемых / доступных только для чтения объектов, или это еще не все? Если целью является создание неизменяемых / доступных только для чтения объектов, то же самое можно сделать в среде, подобной .Net.

Ответы [ 9 ]

13 голосов
/ 13 апреля 2009

Целый раздел посвящен Const Correctness в FAQ. Наслаждайтесь!

7 голосов
/ 13 апреля 2009

const правильность в C ++ - это просто способ точно сказать, что вы имеете в виду:

void foo( const sometype & t ) {
   ...
}

говорит: «Я не буду менять объект, на который ссылается t, и если я попытаюсь, пожалуйста, мистер Компилятор, предупредите меня об этом».

Это не функция безопасности или способ (надежно) создания объектов, доступных только для чтения, потому что тривиально подорвать использование приведения в стиле C.

6 голосов
/ 13 апреля 2009

Бьюсь об заклад, это вопрос мышления. Я работаю с давними людьми C ++ и заметил, что они, кажется, думают на C ++ (конечно, они делают!). Им потребуется время, чтобы начать видеть несколько ответов на те, с которыми они познакомились, чтобы получить «стандартные» ответы, такие как const правильность. Дайте им время и попробуйте обучить их мягко.

Сказав это, мне нравится C ++ 'const' способ гарантий. В основном пользователь интерфейса обещает, что объект, данные за указателем или что-то еще не будет испорчено. Я бы увидел это как значение # 1 правильности const. Значение # 2 - это то, что он может позволить компилятору с точки зрения оптимизации.

Проблема, конечно, в том, что весь стек SW не был создан с учетом констант с нуля.

Я уверен, что C # имеет свой собственный набор парадигм, чтобы сделать то же самое. Это показывает, почему так важно «изучать один новый (компьютерный или естественный) язык в год». Просто использовать свой ум других способов увидеть мир и решить его проблемы.

4 голосов
/ 13 апреля 2009

С помощью const -корректности вы можете выставить изменяемый объект только для чтения , не создавая его копию и не тратя драгоценную память (особенно актуально для коллекций). Я знаю, что среди разработчиков настольных компьютеров есть такая философия CPU-and-memory-дешевые-* , но она все еще имеет значение во встроенном мире.

Кроме того, если вы добавляете сложности владения памятью в C ++, почти всегда лучше не копировать нетривиальные объекты, которые содержат или ссылаются на другие объекты, следовательно, существует метод представления существующих объектов только для чтения. .

3 голосов
/ 13 апреля 2009

Реальный ответ, даже если его действительно трудно понять, если вы его не использовали, заключается в том, что вы теряете выразительность. В языке есть понятия, которые вы не можете выразить в C #, и они имеют значение, они являются частью дизайна, но потеряны при переводе в код.

Это не ответ, а пример:

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

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

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

В C ++ вы можете вернуть константу-ссылку / указатель, и компилятор отключит вызов методов установки (мутирующих методов) в возвращаемом вами экземпляре. Вы получаете и безопасность, которую пользователь не изменит (*), и эффективность в вызове.

Третий, не упомянутый ранее, параметр делает объект неизменным, но это повсеместно запрещает изменения. Совершенно контролируемые изменения объекта будут запрещены, и единственная возможность изменения - создание нового элемента с выполненными изменениями. Это составляет время и пространство.

3 голосов
/ 13 апреля 2009

Отличная книга Скотта Мейера Эффективный C ++ посвятил статью этому вопросу:

ПУНКТ 3: Используйте const, когда это возможно.

Это действительно просвещает вас: -)

2 голосов
/ 13 апреля 2009

C ++ предоставляет множество способов испортить ваш код. Я рассматриваю правильность const как первый эффективный способ наложения ограничений на код, чтобы контролировать «побочные» эффекты (нежелательные изменения).

Обозначение параметра как const (обычно ссылка на const-объект или указатель на const-объект) гарантирует, что переданный объект не может быть изменен, поэтому у вас нет «побочного» эффекта этой функции / метода.

Пометка метода как const гарантирует, что этот метод не изменит состояния объекта, с которым он работает. Если это так, компилятор выдаст ошибку.

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

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

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

1 голос
/ 15 апреля 2009

Мне жаль, что C # не поддерживает правильность констант, как C ++. 95% всех параметров, которые я передаю в функцию, являются постоянными значениями, функция const гарантирует, что данные, передаваемые вами по ссылке, не будут изменены после вызова. Ключевое слово «const» предоставляет документацию, проверяемую компилятором, что очень помогает в больших программах.

1 голос
/ 13 апреля 2009

Достаточно просто обратиться за помощью к компилятору при написании кода, чтобы отстаивать правильность констант. Но сегодня есть дополнительное преимущество: многопоточный код, как правило, легче писать, если вы знаете, где могут изменяться наши объекты, а где нет.

...