Страницы

Поиск по вопросам

воскресенье, 1 декабря 2019 г.

Константные методы

#cpp


Просветите, пожалуйста, на тему константных методов в C++; зачем нужны, в чем преимущества?!
С небольшими примерами кода, если не затруднит.    


Ответы

Ответ 1



Константные методы служат для определения того, что можно сделать с классом без побочного действия на его состояние, и что изменяет его состояние. Пользователю класса, в котором правильно расставлены const, в некоторых случаях, например, удаётся избежать лишнего копирования объектов без потери данных. Также при правильном использовании const на уровне компиляции исключается случайное изменение объекта в методе, который не должен ничего в объекте менять. Например, есть класс типа class A { int a; int b; public: int getA() { b = b + 1;return a; } int getB() { a = a + 1;return b; } }; Здесь мнемоника и семантика немного несоответствуют. Вот хочется думать, что если A x, y; ... bool f = x.getA() == y.getA() && x.getB() == y.getB(); f истина, то x и y в чём-то похожи, но внутренности класса реализованы не так. Пользователь класса должен быть уверен, что геттер ничего не испортит. Хороший разработчик класса должен явно описывать характер поведения метода с помощью const или отсутствия const class A { int a; int b; public: int getA() const { return a; } int getB() const { return b; } }; Но если вам вдруг понадобится делать прогу, в которой есть что-то вроде подсчёта обращений к переменной, то семантика геттеров заставляет употребить const, но счётчик обращений нужно увеличивать. Для этого случая есть слово mutable! Этим словом мы пометим поля, которые вроде как бы члены класса, но они не отражают что ли его состояние class A { int a; int b; mutable int cntA; mutable int cntB; public: int getA() const { cntA++; return a; } int getB() const { cntB++; return b; } };

Ответ 2



Несколько слов о применении константных методов. Классы с константными методами удобно применять: 1.Когда над проектом работают несколько программистов. Когда проектируется класс разработчик сразу определяет, что и при каких условиях может меняться, а что должно остаться неизменным. Константные классы тут как раз к месту для построения всех "запретительных заборов", чтобы другой разработчик случайно не изменил состояние объекта. Как правило, классы с константными методами не имеют конструктор по умолчанию, а только конструкторы, зависящие от каких-то объектов. Это очень удобно, так как все члены будут инициализированы. Кстати, это единственный способ инициализации константных членов. 2.Использование объектов const. Если создается константный объект, то для обращения к его методам и членам надо использовать константные методы. Например, если в функцию передается указатель на объект, но хочется обезопасить его от изменения, то нужно его объявлять как const

Ответ 3



В нестатические методы класса компилятор неявно передаёт константный указатель на объект от которого был вызван метод, его сигнатура T* const this // адресс на который указывает this поменять нельзя благодаря ему можно связать обращение к переменным и методам с фактическим адрессом экземпляра. Следовательно код: void f() { m_a = 10; } эквивалентен void f() { this->m_a = 10; } В случаи с константными методами, вы меняем два поведения: Теперь данный метод может быть вызван для константного объекта. const Foo a; a->f(); // only if f() is const method Теперь внутрь данных методов передаётся константный указатель на константу. const T* const this; // адресс и состояние объекта на который указывает this поменять нельзя следовательно void f() { this->m_a = 10; // ошибка нельзя менять состояние константного объекта } Преймущества константного метода: можно вызывать для константных объектов и указателей на константу. применения grammar const (всё что должно быть const - должно иметь данный спецификатор) - если метод не меняет объект то почему бы программисту явно не указать это себе, другим программистам и компилятору? Можно перегрузить метод через его константность: struct Array { int x; int operator[]( int index ) const { return x; } int& operator[]( int index ) { return x; } }; int main() { Array a; a[1] = 10; // int& operator[]( int index ) // ok const Array b; b[1] = 10; // int operator[]( int index ) const // error: `int` is not lvalue }

Ответ 4



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

Ответ 5



Все становится понятно если разобраться как "работают" методы классов. class A { public: int GetSome(); void SetSome(int some); } Для компилятора любой вызова метода класса по сути выглядит вот так: int GetSome(const A* const this); void SetSome(A* const this,int some); Из чего очевидно, что при попытке изменить константный объект, вы получите по рукам. И из этого становится понятно, почему дружественные функции, статические функции не могут быть константными.

Ответ 6



А теперь на русском: Константный метод, это такой метод, который не меняет свойств/членов класса. При попытке откомпилировать код, который содержит константный метод изменяющий класс - компилятор выдаст ошибку. У константных объектов, могут быть вызваны только константные методы. Константных функций небывает. Как и константных классов ;)

Ответ 7



Очень хорошо все объяснено в книжке Джефф Элджер. С++: Библиотека программиста - СПб: Издательство "Питер", 2000. Если можно, то могу здесь привести цитату из нее.

Комментариев нет:

Отправить комментарий