о постоянной функции-члена [дубликата]

На этот вопрос уже есть ответ:

Я встретил два объяснения функции-члена const

class A{
  public:
  ...
  void f() const {}
  ...
}
  1. , это означает, что она могла только постоянные члены;
  2. это означает, что он не изменяет никакие члены;

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

Спасибо!

8
задан James Thompson 27 December 2009 в 18:37
поделиться

4 ответа

В функции const member можно просмотреть все значения членов класса, а в некоторых случаях можно даже изменить значение переменных членов. Первое объяснение некорректно, я не знаю, откуда оно взялось. Второе объяснение корректно, но с некоторыми исключениями.

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

mutable float my_rank;

Также можно нарушить const-корректность в классе, сделав ссылку на себя так:

Class* self = const_cast<Class*> (this);

Хотя технически это допустимо в Си++, обычно это считается плохой формой, так как отбрасывает все модификаторы const вашего дизайна. Не делайте этого, если на самом деле вам это не нужно, и если вы обнаружите, что вам приходится делать это довольно часто, что говорит о проблемах с вашим дизайном. C++ FAQ очень хорошо описывает это.

Вот две ссылки на случай, если Вы захотите прочитать больше:

18
ответ дан 5 December 2019 в 06:23
поделиться

В простом смысле, в функции const нельзя изменить состояние объекта.

В функции const этот указатель ведёт себя как указатель const на данные const, где, как и в неконстантной функции, он ведёт себя как указатель const на данные.

void foo() const  --> const ClassName * const this (so you can't alter data)

void foo() --> ClassName * const this (so you can alter data)

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

Как показал Джеймс Томпсон, вы даже можете изменить состояние объекта, удалив constness, если хотите.

class Bar
{
    int bar;
    public:
     void foo() const
     {
        this->bar = 0; //flashes error 

        Bar * const thisClass = const_cast<Bar * const>(this);
        thisClass->bar = 0;  
     }
};

Также в функции const могут быть изменены мутирующие члены данных.

5
ответ дан 5 December 2019 в 06:23
поделиться

Я думаю, что случай 1 после некоторого уточнения может касаться ситуации, когда у вас есть const-объект типа A. В таком случае вы можете вызывать только его членские функции, объявленные как const like f() в данном случае. Поэтому, согласно вашей записи, вы должны предполагать, что "it" - это вызывающая функция-член на объекте типа const A. Может быть, вам стоит пересмотреть определение, которое вы нашли, имея в виду это предположение.

.
1
ответ дан 5 December 2019 в 06:23
поделиться

Они оба правильные.

Функция константного члена не может изменить состояние объекта.

  • Это означает, что она может читать (но не изменять) все переменные-члены. Это также означает, что она может только вызывать другие функции-члены const
    . Другие методы, которые гарантируют, что состояние объекта не изменится.

Над Джеймсом также упоминаются мутирующие члены.
. Так что здесь я тоже должен остановиться на них.

Переменная с мутирующим членом - это переменная, которая не является частью состояния объекта (компилятор не считает ее частью состояния объектов). Так же к ней следует относиться. Любая переменная-член, содержащая информацию о состоянии объекта, должна быть помечена как NOT mutable. Вы должны использовать ее только для хранения временной информации, которая может быть перестроена из состояния объектов.

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

Также Джеймс упоминает выше отбрасывание constness с помощью const_cast.

За исключением очень специфических ситуаций, когда вы знаете объект CAN NEVER BE const, делать это считается повсеместно плохой идеей. Так как это приводит непосредственно к неопределенному поведению. Если вам нужно отбросить constness, то в вашей программе произошло что-то очень плохое.

На самом деле, я могу вспомнить только одну ситуацию, где это происходит нормально. И тогда я не хочу коммитировать её в код, не идя сначала и не проводя исследований, чтобы не выглядеть глупо.

.
2
ответ дан 5 December 2019 в 06:23
поделиться
Другие вопросы по тегам:

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