Урок 125. Статические методы класса

   ⁄ 

 Обновлено 18 Мар 2018  ⁄ 

⁄   479

В предыдущем уроке мы узнали, что статические переменные-члены — это члены, которые принадлежат классу, а не его объектам. Если статические переменные-члены являются открытыми, то мы можем получить к ним доступ напрямую через имя класса и оператор разрешения области видимости. Но что, если статические переменные-члены являются закрытыми? Рассмотрим следующий код:

В этом случае мы не можем напрямую получить доступ к Anything::s_value из main(), так как этот член является private. Обычно доступ к закрытым членам класса осуществляется через методы public. Хотя мы могли бы создать обычный метод для получения доступа к s_value, но нам тогда бы пришлось создавать объект этого класса для использования метода! Есть вариант получше – мы можем сделать метод статическим.

Подобно статическим переменным-членам, статические методы не привязаны к какому-либо одному объекту класса. Вот пример выше, но уже со статическим методом:

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

Статические методы не имеют указателя this *

У статических методов есть две интересные особенности. Во-первых, поскольку статические методы не привязаны к объекту, то они не имеют скрытого указателя this! Здесь есть смысл, так как указатель this всегда указывает на объект, с которым работает метод. Статические методы могут не работать через объект, поэтому и указатель this не нужен.

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

Еще пример

Статические методы можно определять вне тела класса. Это работает так же, как и с обычными методами. Например:

Результат:

The next ID is: 1
The next ID is: 2
The next ID is: 3
The next ID is: 4



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

Предупреждение о классах со всеми статическими членами

Будьте осторожны при написании классов со всеми статическими членами. Хотя такие «чисто статические классы» могут быть полезны, но они также имеют свои недостатки.

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

Во-вторых, из урока о глобальных переменных мы знаем, что глобальные переменные опасны, поскольку любая часть кода может изменить их значения и в конечном итоге изменит другие фрагменты, казалось бы, не связанного кода (детальнее здесь). То же самое справедливо и для «чисто статических» классов. Поскольку все члены принадлежат классу (а не его объектам), а классы имеют глобальную область видимости, то в «чисто статическом классе» мы объявляем глобальные функции и переменные со всеми минусами, которые они имеют.

C++ не поддерживает статические конструкторы

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

Если ваша статическая переменная может быть инициализирована напрямую, то конструктор не нужен: вы можете определить статическую переменную-член, даже если она является private. Мы делаем это в примере выше с s_nextID. Вот еще один пример:

Если для инициализации вашей статической переменной-члена требуется выполнить код (например, цикл), то есть несколько разных способов это сделать. Следующий способ является лучшим из них. Хотя это может быть немного сложно (сейчас), и, вероятно, вам это никогда не понадобится, то вы можете спокойно пропустить оставшуюся часть этого урока, если хотите.

Результат:

o a u i e

При определении статического члена s_initializer вызовется конструктор по умолчанию _nested() (так как s_initializer является объектом класса _nested). Мы можем использовать этот конструктор для инициализации любых статических переменных-членов класса Something. Самое крутое здесь – это то, что весь код инициализации скрыт внутри исходного класса со статическим членом.

Итого

Статические методы могут использоваться для работы со статическими переменными-членами класса. Для работы с ними не требуется создавать объекты класса.

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

Оценить статью:

Звёзд: 1Звёзд: 2Звёзд: 3Звёзд: 4Звёзд: 5 (5 оценок, среднее: 5,00 из 5)
Загрузка...
Подписаться на обновления:

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

ПОДПИСЫВАЙТЕСЬ

НА КАНАЛ RAVESLI В TELEGRAM

@ravesli

ПОДПИСАТЬСЯ БЕСПЛАТНО