2009-03-24 2 views
8

Разработчик в команде, которую я контролирую, предпочитает объявление переменных как констант в своих тестах, например.().Ваше мнение об объявлении констант внутри методов ...?

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

Я всегда думал о константах как о чем-то, что должно быть объявлено на уровне класса. Однако я вижу точку зрения разработчика.

Как вы знаете? И, в отличие от тестов, вы бы объявляли константы в обычных методах? Если да, почему?

ответ

3

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

3

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

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

9

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

20

В общем, я думаю, что это всегда хорошая идея, чтобы сделать ваши намерения очистить этот путь, по целому ряду причин:

  • Это легче понять, что вы имели в виду, когда вы написали.
  • Другим людям легче рассуждать о коде, когда они его читают.
  • Проще компилятор сделать выводы о том, что вы хотите сделать.
  • Проще компилятор предотвращает логические ошибки.

Выполнение переменных констант - вполне законный способ выполнить все вышеизложенное, в конкретном случае намереваясь «Я не хочу, чтобы эта переменная меняла свое значение».

3

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

С точки зрения C#, это также оказывает влияние на закрытий:

const int i = 27; 
Func<Foo,bool> predicate = foo => foo.Bar == i; 

отличается:

int i = 27; 
Func<Foo,bool> predicate = foo => foo.Bar == i; 

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

+0

Разве компилятор не достаточно умный, чтобы обнаружить это? – erikkallen

+0

@erikkallen: Да, конечно. Вот почему они разные. Если компилятор не смог его обнаружить, то с ними нельзя было бы обращаться иначе. –

+0

@Tomalak: Да, но компилятор также может быть достаточно умным, чтобы знать, что значение не изменяется после закрытия. – erikkallen

5

Если вы собираетесь использовать статически типизированный язык, то почему бы просто не пройти целых девять ярдов? Используйте const, чтобы указать, что вы не хотите, чтобы значение менялось после первого присваивания. Пусть компилятор вас убьет, если вы goof.

мне очень понравилось const ключевого слова в параметрах метода C++ именно по этой причине ...

1

Объявляя переменную константу предотвратит случайное изменение значения. Это также может привести к оптимизации компилятора.

0

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

1

Я склонен объявлять любое значение, которое не меняет const/final, и поощрять других к командам, с которыми я работаю, делать то же самое. Обычно в Java, где final означает «присваивать один раз и один раз», а не «const» инициализируется и не изменяется, вы можете создавать методы, в которых единственными не постоянными значениями являются итераторы цикла.

1

Делайте это везде, где это возможно:

  • это сделать код легким для чтения;
  • он просит компилятор проверить ошибки Повода:

    void some_class1::doSomething(const some_class2& cs2) 
    { 
        // code 
        cs2 = cs2; // !!! misspelling cs2 instead cs2_ 
        // 
    } 
    
  • это помогает вам с совместимостью с const -correct кода;

  • это помогает с инкапсулированием.
10

От Effective C++ Скотт Мейерс (глава 3):

Использование const всякий раз, когда это возможно.

Замечательная вещь const в том, что она позволяет определить семантическое ограничение - конкретный объект должен не быть изменен - ​​и компиляторы применять это ограничение. Это позволяет вам сообщать как компиляторам, так и другим программистам, что значение должно оставаться неизменным. Всякий раз, когда это так, вы должны быть уверены в этом, потому что таким образом вы заручитесь помощью своих компиляторов, чтобы убедиться, что ограничение не нарушено.

0

Для испытаний это, безусловно, отлично. Что касается «обычного» кода, вы можете смотреть на него с двух сторон. С одной стороны, объем всего кода должен быть как можно меньше.С другой стороны, вы могли бы сказать, что константа, скорее всего, будет использоваться по всему классу, и поэтому должна быть объявлена ​​на уровне класса во все времена, чтобы предотвратить двойные константы.

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

2

Преимущество объявления его const заключается в том, что вы не можете «случайно» изменить его в неясном виде, который может пропустить проверку кода. Например, передав его ссылкой в ​​функцию, которая изменяет свой параметр.

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

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

Я стараюсь использовать его, когда помню, и не потею, если забываю. Я использую большинство из них, когда мне нужно удалить const из переменной. Это говорит мне, что моя первоначальная концепция этой переменной была неправильной, и мне нужно тщательно проверить, что никакое выражение, использующее ее, не полагается на нее, не меняется. Учитывая, что C++ имеет ключевое слово const, если вы собираетесь писать код, который зависит от переменной, не изменяющейся, вы также можете получить компилятор на вашей стороне.

Обычно не стоит беспокоиться о оптимизации компилятора. Хороший компилятор (gcc) может сказать, что если вы не изменяете переменную и не принимаете никаких ссылок на нее, тогда она может применить соответствующие оптимизации, отметите ли вы ее const или нет.

3

Многие опытные разработчики на С ++ на самом деле считают, что значение «const» должно быть по умолчанию, и вам нужно явно объявить что-то непостоянным. Конечно, используйте const, когда это имеет смысл. Если что-то не должно меняться внутри функции, сделайте ее const. Это ничего не стоит, и это помогает объявить намерение.

Смежные вопросы