Что означает оператор const при использовании с методом в C ++?

Учитывая такое заявление:

class A {
public:
    void Foo() const;
};

Что это означает?

Google показывает это:

Функции-члены следует объявлять с ключевым словом const после них, если они могут работать с объектом const (this). Если функция не объявлена ​​как const, in не может применяться к объекту const, и компилятор выдаст сообщение об ошибке.

Но меня это несколько сбивает с толку; Кто-нибудь может выразить это лучше?

Спасибо.


c++
person Bernard    schedule 08.09.2008    source источник


Ответы (7)


Рассмотрим вариант вашего класса A.

class A {
public:
    void Foo() const;
    void Moo();

private:
    int m_nState; // Could add mutable keyword if desired
    int GetState() const   { return m_nState; }
    void SetState(int val) { m_nState = val; }
};

const A *A1 = new A();
A *A2 = new A();

A1->Foo(); // OK
A2->Foo(); // OK

A1->Moo(); // Error - Not allowed to call non-const function on const object instance
A2->Moo(); // OK

Ключевое слово const в объявлении функции указывает компилятору, что функция по контракту обязана не изменять состояние A. Таким образом, вы не можете вызывать функции, отличные от const, в A::Foo или изменять значения переменных-членов.

Чтобы проиллюстрировать, Foo () может не вызывать A::SetState, поскольку он объявлен не-const, A::GetState однако это нормально, потому что он явно объявлен const. Член m_nState также не может быть изменен, если он не объявлен с ключевым словом mutable.

Одним из примеров такого использования const является получение функцией «геттера» значения переменных-членов.

@ 1800 Информация: Я забыл про изменчивый!

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

person Henk    schedule 08.09.2008

Это не ответ, просто побочный комментарий. Настоятельно рекомендуется как можно больше объявлять переменные и константы const.

  1. Это сообщает о ваших намерениях пользователям вашего класса (даже / особенно вам самому).
  2. Компилятор сохранит честность в отношении этих намерений. - то есть это как документация, проверенная компилятором.
  3. По определению, это предотвращает изменения состояния, которых вы не ожидали, и, возможно, может позволить вам делать разумные предположения в ваших методах.
  4. const имеет забавный способ распространения через ваш код. Таким образом, это действительно хорошая идея начать использовать const как можно раньше и как можно чаще. Решение начать const исправление кода в конце игры может быть болезненным (простым, но раздражающим).

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

person Pat Notz    schedule 08.09.2008

Функции с квалификатором const не могут изменять какие-либо переменные-члены. Например:

class A
{
    int x;
    mutable int y;

    void f() const
    {
      x = 1; // error
      y = 1; // ok because y is mutable
    }
};
person 1800 INFORMATION    schedule 08.09.2008

Объекты C ++ могут быть объявлены как константы:

const A obj = new A();

Когда объект является константным, единственными функциями-членами, которые могут быть вызваны для этого объекта, являются функции, объявленные как константы. Создание объекта const можно интерпретировать как создание объекта только для чтения. Объект const не может быть изменен, т.е. никакие элементы данных объекта не могут быть изменены. Объявление функции-члена const означает, что функции не разрешено вносить какие-либо изменения в элементы данных объекта.

person dfjacobs    schedule 08.09.2008
comment
Err ... const A * obj = new A (); ... Вы забыли звезду ... :-) - person paercebal; 18.09.2008

Два рекомендуемых передовых метода, основанных на опыте:

(1) По возможности объявляйте константные функции. Сначала я обнаружил, что это просто дополнительная работа, но затем я начал передавать свои объекты функциям с сигнатурами типа f (const Object & o), и внезапно компилятор отключил строку в f, такую ​​как o.GetAValue (), потому что Я не пометил GetAValue как константную функцию. Это может вас удивить, особенно когда вы подклассифицируете что-то и не помечаете свою версию виртуальных методов как const - в этом случае компиляция может завершиться неудачно для какой-то функции, о которой вы никогда раньше не слышали, которая была написана для базового класса.

(2) По возможности избегайте изменяемых переменных. Заманчивой ловушкой может быть разрешение операциям чтения изменять состояние, например, если вы создаете «умный» объект, который выполняет ленивые или асинхронные операции ввода-вывода. Если вы можете справиться с этим с помощью только одной небольшой изменяемой переменной (например, bool), то, по моему опыту, это имеет смысл. Однако, если вы обнаружите, что помечаете каждую переменную-член как изменяемую, чтобы некоторые операции оставались константными, вы теряете цель ключевого слова const. Что может пойти не так, так это то, что функция, которая думает, что она не изменяет ваш класс (поскольку она вызывает только методы const), вызывает ошибку в вашем коде, и может потребоваться много усилий, чтобы даже понять, что эта ошибка находится в вашем классе, поскольку другой кодировщик (справедливо) предполагает, что ваши данные являются константными, потому что он или она вызывает только константные методы.

person Tyler    schedule 12.09.2008

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

Кроме того, вы легко столкнетесь с проблемами, если методы, которые должны быть константными, не являются! Это также будет проползать через код и делать его все хуже и хуже.

person MP24    schedule 12.09.2008

это приведет к тому, что метод не сможет изменить какие-либо переменные-члены объекта

person John Boker    schedule 08.09.2008