Вопрос по const, c++ – const (c ++) является необязательным?

4

согласно некоторым урокам, которые я читал некоторое время назад,«Уста» объявление делает переменную «константой», то есть она не может измениться позже.
Но я нахожу это объявление const неудобным, так как компилятор иногда выдает такие ошибки, как
"cannot convert const int to int"
или что-то типа того.

и я обманываю, удаляя это так или иначе.

вопрос: при условии, чтоя стараюсь не менять переменную в моем исходном кодеМогу ли я с радостью забыть об этом const материале?

заранее спасибо

Вы должны использоватьCгораздо легче выстрелить себе в ногу (и вы не рискуете ногой) Matthieu M.
Другими словами: «Я делаю ошибки в правильности, если я никогда не ошибаюсь в правильности, могу ли я отказаться от использования const?» Steve S
Что-то, что полезно использоватьmutable поля класса, когда вам нужно только «логическое» постоянство, но не «физическое». Конечно, этот подход более подвержен ошибкам, но иногда нет лучшего пути. parallelgeek

Ваш Ответ

11   ответов
0

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

3

особенно в отношении ссылок. Рассматривать:

void f(const MyClass& m);
void f(const int& i);

// ...

f(MyClass()); // OK, can pass temporary as const reference
f(5); // OK as well, 5 is a temporary int

Если вы считаете 'const' необязательным и избавляетесь от него:

void f(MyClass& m);
void f(int& i);

// ...

f(MyClass()); // Error, cannot pass temporary as non-const reference
f(5); // Error, same as above
Да, конечно! Просто для начала, как насчет:SetPosition(vector2(0, 0)); AshleysBrain
Действительно ли полезно использовать временные значения скалярного типа, которые не существуют после вызова функции? parallelgeek
Возможно, я глуп, но как пример, который вы привели, объясняет, почему полезно дать функции ссылку на неизменяемый тип int? parallelgeek
6

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

Появляется сообщение об ошибке, потому что вы пытаетесь изменитьconst int, Просто присваивая значение (неконстантному)int, вы измените это, как вы хотите.

Const помогает вам, постарайтесь разбросать его побольше и послушайте компилятор. Это поможет вам создавать лучший код.

Компилятор может вообще не использоватьconst-информация как помощь при оптимизации. Andreas Brinck
@Andreas: в общем, правда, хотя на практике я видел код, который выиграл от объявления const автоматической переменной. Это было на старом GCC, однако, и новый обнаружил, что неконстантная переменная никогда не изменялась и применял одну и ту же модификацию. В этом случае оптимизация для использования непосредственного значения вместо целочисленного регистра, который, конечно, работает только потому, что моя переменная была инициализирована со значением, которое мог видеть компилятор. Вместо того, чтобы пытаться угадать, что компилятор может или не может сделать, в теории и на практике, я просто использую const, когда могу. Steve Jessop
@ Steve Вот почему я написал «в общем»;) Я бы сказал, что это общее заблуждение, чтоconst помогает компилятору оптимизировать. Вы должны использовать его везде, где только можете, но по разным причинам. Andreas Brinck
@ Андреас: Извините, возможно, я не дал понять, что я с вами согласен. Мой пример был призван показать, насколько слабой была ситуация, которая фактически имела значение для оптимизации: у компилятора была необходимая информация для оптимизации без констант, что подтверждается тем фактом, что более поздняя версия делает это. Это просто не было достаточно умно. Оптимизации, где я умнее компилятораочень поздняя стадия ;-) Steve Jessop
51

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

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

+1 Хороший ответ. Это не только отличная помощь во время компиляции, но и хорошая форма документации. Вы можете видеть, какие переменные могут изменяться, а какие нет, что может сэкономить много времени при чтении кода. helpermethod
+1 "Вы можете позволить компилятору сообщить вам сейчас или попросить отладчик сообщить вам позже." Очень хорошо. Beta
+1 Единственный раз, когда я не использую const в максимально возможной степени, это когда существующее ПО не является константным, и я реорганизую его, чтобы он был бит за битом. Я предпочел бы знать прямо во время компиляции, что я изменяю то, что я не собирался. Mark B
@helpermethod, но const на самом деле не мешает изменению переменной, потому что люди все еще могут ее правильно использовать ... это беспокоит меня уже несколько дней :) MetaGuru
-4

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

const double PI = 3.14159265358979;

PI=4; // generates a compiler error (good)

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

class A {
private:
  const int num;
public:
  A(int x, int y) : num(0) { // oops, I don't yet know what num should be
    while ( ... ) {

    }
    num = ...;
  }
};

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

class A {
private:
  const int num;
  int computeNum(int x, int y) { ... }
public:
  A(int x, int y) : num(f(x,y)) {
  }
};

Иногда у вас есть значение, которое обычно должно быть константным, но вы хотите выборочно переопределить его, когда оно семантически имеет смысл. Например, номера социального страхования не меняются, если только ваша личность не украдена. Таким образом, у вас есть только один метод с именем createNewSSN (), который изменяет в противном случае постоянную ssn

class Person {
private:
  const int ssn;
public:
  Person(int ssn_) : ssn(ssn_) {}

  void createNewSSN(int newssn) {
    log << "Changed SSN: " << ssn << " to " << newssn << "\n";
    *(int*)&ssn = newssn; // trust me, this is a special case....
  }
};
Для всех стандартных наркоманов соответствующий отрывок - 7.1.5.1/4 «За исключением того, что любой член класса, объявленный непостоянным (7.1.1), может быть изменен, любая попытка изменить объект const в течение его времени жизни (3.8) приводит к неопределенному поведению». Andreas Brinck
"Пи ровно три!" Emile Cormier
Этот «трюк» - неопределенное поведение. Я серьезно надеюсь, что ваши SSN не будут так манипулироваться. jalf
Это плохой совет по нескольким причинам. Во-первых, если SSN может измениться, тогда переменная-член не должна быть const. Во-вторых,*(int*) уловка вызывает неопределенное поведение. В-третьих, если вы не знаете значение константного члена во время сборки, то, когда компилятор выдаст вам ошибку, он сообщит вам, что ваш дизайн неверен. Это не говорит о том, что пришло время стать компортатором компилятора. John Dibling
Этот трюк * (int *) & n является новым для меня, но выглядит как аналог const_cast. Есть причина, по которой const_cast назвали худшей функцией в C ++, и я никогда не видел, чтобы она использовалась, кроме как как обходной путь, чтобы обойти плохой код, который был сделан политически неприкосновенным. Beta
1

Можно забудьте об этом, но разве это не хорошо, если компилятор навязывает это вам? Таким образом, ваши «постоянные» переменные на самом деле остаются постоянными.

14

и к функции (делая ее неспособной изменить другие вещи).

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

@Beta спасибо, и нет ничего конкретного, я только что читал исходный код в последнее время, я прочитал один блог, где парень бредил о том, как прекрасен исходный код Doom 3, и одной из причин было все правильное использование const, поэтому я был просто исследую прочь :) MetaGuru
@Dov, правда, const не может применяться квсе функции только длячлен функции. И даже функция const (member) может изменитьсянемного другие вещи. Я пытался для краткости, а не строгости. Beta
@ioSamurai: это мешает кому-то изменить егослучайно, случайно, Да, некоторые люди знают оconst_cast и не понимаю, насколько это опасно, и были споры о том, должно ли это быть на языке или нет. Вы имеете в виду конкретную проблему? Beta
Я изучал как и почему const, но я не могу поколебать тот факт, что, хотя предполагается, что код не может изменить переменную, на самом деле это не так, потому что кто-то все еще может отбросить const ... так что я все еще смотрю ... MetaGuru
3

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

«если вы и все, с кем работаете, никогда не ошибаются», что, конечно, невозможно. John Dibling
1

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

это необязательно в том смысле, что вам не нужно использовать его, если вы не хотите кодировать с этим стилем. Независимо от его достоинств. Steve
Не всегда опционально Например, константные ссылки действуют не так, как неконстантные ссылки. Zan Lynx
1

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

Итак, в итоге вам лучше подумать, почему выдолжен сделай что нибудьconst и когда ты не должен.

Еще один метод изучения того, почему const имеет значение - попытаться сделатьвсе const сначала, пока у вас не будет веских причин что-то изменить, затем, и только потом, удалите минимальное количество conts, пока оно не заработает снова.

Рад видеть, что вы думаете о проблеме - это больше, чем большинство.

2

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

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

const также фиксирует намерение не изменять и предотвращает случайное назначение.

Делаяconst Использовать обязательно не нужно, это очень полезно и полезно.

Вот полезное объяснение, которое вы можете проверить:http://duramecho.com/ComputerInformation/WhyHowCppConst.html

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