Членское присвоение в функции константы

Попробуйте ls -U или ls -f.

ls, по умолчанию, сортирует файлы в алфавитном порядке. Если у Вас есть 2 миллиона файлов, тот вид может занять много времени. Если ls -U (или возможно ls -f), то имена файлов будут сразу распечатаны.

9
задан Fredrik Ullner 25 November 2009 в 12:09
поделиться

5 ответов

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

const_cast<myType*&>(myMember) = new myType();

или [из другого ответа, спасибо: P]:

const_cast<ThisType*>(this)->myMember = new myType();

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

Как вы можете видеть из яростных дебатов вокруг этого вопроса, волевое использование mutable и большого количества const_cast определенно может быть симптомом неприятных запахов в вашем коде. С концептуальной точки зрения, отказ от константности или использование mutable может иметь гораздо более серьезные последствия. В некоторых случаях правильным решением может быть изменение метода на неконстантный, т. Е. Признать тот факт, что он изменяет состояние.

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

8
ответ дан 4 December 2019 в 06:30
поделиться

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

17
ответ дан 4 December 2019 в 06:30
поделиться

const_cast почти всегда является признаком ошибки проекта. В вашем примере либо func () не должно быть const , либо myMember должно быть mutable .

Вызывающий func () ожидает, что ее объект не изменится; но это означает «не меняться так, как она может заметить»; то есть, чтобы не менять свое внешнее состояние. Если изменение myMember не изменяет внешнее состояние объекта, это то, для чего предназначено ключевое слово mutable ; в противном случае func () не должно быть const , потому что вы нарушите гарантии своей функции.

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

6
ответ дан 4 December 2019 в 06:30
поделиться
class Class{
int value;
void func()const{
const_cast<Class*>(this)->value=123;
}
};
5
ответ дан 4 December 2019 в 06:30
поделиться

Как написал Стив Гилхэм, mutable - это правильный (и короткий) ответ на ваш вопрос. Я просто хочу намекнуть в другом направлении. Может быть, в вашем сценарии можно использовать (или более одного) интерфейса? Возможно, вы сможете понять это из следующего примера:

class IRestrictedWriter // may change only some members
{
public:
  virtual void func() = 0; 
}

class MyClass : virtual public IRestrictedWriter
{
public:
  virtual void func()
  {
    mValueToBeWrittenFromEverybody = 123; 
  }

  void otherFunctionNotAccessibleViaIRestrictedWriter()
  {
    mOtherValue1 = 123;
    mOtherValue2 = 345;
  }

  ...   
}

Итак, если вы передадите некоторой функции IRestrictedReader * вместо const MyClass * , она может вызвать func и, таким образом, измените mValueToBeWrittenFromEverybody , тогда как mOtherValue1 является своего рода «const».

. Я считаю изменяемым всегда чем-то вроде хака (но иногда его использую).

1
ответ дан 4 December 2019 в 06:30
поделиться
Другие вопросы по тегам:

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