Выбрать главу

Узелок на память. При объявлении члена класса статическим вы обеспечиваете создание только одной его копии, которая будет совместно использоваться всеми объектами этого класса.

Если static-переменная является открытой (т.е. public-переменной), к ней можно обращаться напрямую через имя ее класса, без ссылки на какой-либо конкретный объект. (Безусловно, обращаться можно также и через имя объекта.) Рассмотрим, например, эту версию класса ShareVar.

class ShareVar {

 public:

  static int num;

  void setnum(int i) { num = i; };

  void shownum() { cout << num << " "; }

};

В данной версии переменная num является public-членом данных. Это позволяет нам обращаться к ней напрямую, как показано в следующий инструкции.

ShareVar::num = 100;

Здесь значение переменной num устанавливается независимо от объекта, а для обращения к ней достаточно использовать имя класса и оператор разрешения области видимости. Более того, эта инструкция законна даже до создания каких-либо объектов типа ShareVar! Таким образом, получить или установить значение static-члена класса можно до того, как будут созданы какие-либо объекты.

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

Можно также объявить статической и функцию-член, но это — нераспространенная практика. К статической функции-члену могут получить доступ только другие static-члены этого класса. (Конечно же, статическая функция-член может получать доступ к нестатическим глобальным данным и функциям.) Статическая функция-член не имеет указателя this. Создание виртуальных статических функций-членов не разрешено. Кроме того, их нельзя объявлять с модификаторами const или volatile. Статическую функцию-член можно вызвать для объекта ее класса или независимо от какого бы то ни было объекта, а для обращения к ней достаточно использовать имя класса и оператор разрешения области видимости.

Применение к функциям-членам модификаторов const и mutable

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

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

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

class X {

  int some_var;

 public:

  int f1() const; // const-функция-член

};

Как видите, модификатор const располагается после объявления списка параметров функции.

Цель объявления функции как const-члена — не допустить модификацию объекта, который ее вызывает. Например, рассмотрим следующую программу.

/* Демонстрация использования const-функций-членов. Эта программа не скомпилируется.

*/

#include <iostream>

using namespace std;

class Demo {

  int i;

 public:

  int geti() const {

   return i; // все в порядке

  }

  void seti (int x) const { i = x; // ошибка! }

};

int main()

{

 Demo ob;

 ob.seti(1900);

 cout << ob.geti();

 return 0;

}

Эта программа не скомпилируется, поскольку функция seti() объявлена как const-член. Это означает, что ей не разрешено модифицировать вызывающий объект. Ее попытка изменить содержимое переменной i приводит к возникновению ошибки. В отличие от функции seti(), функция geti() не пытается модифицировать переменную i, и потому она совершенно приемлема.