Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
63
Добавлен:
16.02.2016
Размер:
455 Кб
Скачать

Статические члены класса

Члены класса могут быть объявлены с модификатором static. Статический член класса может рассматриваться как глобальная переменная или функция, доступная только в преде­лах области класса.

Данное-член класса, определенное с модификатором static, разделяется всеми представителями этого класса, так как на са­мом деле существует только один экземпляр этой переменной. На самом деле, память под статические данные-члены выделяется, даже если нет никаких представителей класса. Поэтому класс должен не только объявлять статические данные-члены, но и определять их. Например:

class AnyClass

{

public:

AnyClass();

//объявление статического данного-члена

static int count;

};

//определение статического данного-члена

int AnyClass::count = 0;

Заметим, что хотя к статическим данным-членам, объявлен­ным в разделе public класса, можно обращаться с помощью конструкции, использующих имя объекта:

<объект>.<данное_член>

или

<указатель_на_объект>- ><данное_член>,

лучше использовать форму вызова

<имя_класса>: : <данное_член>,

которая является более правильной, так как отражает тот факт, что соответствующее данное-член является единственным для всего класса. Если статические данные-члены объявлены как закрытые, то доступ к ним можно получить с помощью обычных функций-членов. Доступ к статическим данным-членам с помо­щью обычных функций-членов ничем не отличается от доступа к другим данным-членам, но для этого необходимо создать хотя бы один объект данного класса. В связи со сказанным выше, можно дать следующие рекомендации:

• применяйте статически данные-члены для совместного использования данных несколькими объектами класса;

• ограничьте доступ к статическим данным-членам, объя­вив их в разделе protected или private.

Рассмотрим пример использования статического данного-члена класса:

#include <iostream.h>

class T

{

public:

T(){ObCount++;}

~T(){ObCount--;}

static int ObCount;

//...

private:

int x;

};

int Т::ObCount = 0;

int main()

{

T* pOb = new Т[5];

cout « " Имеется " « Т::ObCount « " объектов типа Т\n";

delete[] рОb;

return 0;

}

В этом примере статическое данное-член просто ведет учет созданных объектов. При выполнении программа выводит на экран:

Имеется 5 объектов типа Т

Особенностью использования статических функций-членов является то, что они также определены в единственном экземпля­ре и не являются безраздельной собственностью какого-то пред­ставителя класса. В связи с этим им не передается указатель this. Эта особенность статических функций-членов использует­ся при написании функций-обработчиков прерывании и callback-функций (при программировании для Windows).

Из сказанного выше вытекает несколько важных следствий:

• статическая функция-член может вызываться независимо от того, существует или нет какой-либо представитель класса;

• статическая функция-член может манипулировать только статическими данными-членами класса и вызывать толь­ко другие статические функции-члены класса;

• статическая функция-член не может быть объявлена с модификатором virtual.

Приведем пример использования статической функции-члена. Он представляет собой слегка отредактированный предыдущий пример:

#include <iostream.h>

class T

{

public:

Т(){ObCount++;}

~Т(){ObCount--;}

//...

static int GetCounts(){return ObCount;}

private:

int x;

static int ObCount;

};

int Т::ObCount = 0;

int main ()

{

Т* рОb = new Т[5] ;

cout « "Имеется " « Т::GetCounts() « " объектов типа Т\n";

delete[] pOb;

return 0;

}

Константные объекты и константные функции-члены класса.

Ключевое слово mutable

Функция-член класса может быть объявлена с модификато­ром const, который следует за списком параметров. Такая функция не может изменять значение данных-членов класса и не может вызывать не константные функции-члены класса. Приве­дем пример объявления константной функции-члена класса:

class Coord

{

int х,у;

public:

Coord(int _x, int _y);

void SetVal(int _x, int _y);

//константна функция-член

void GetVal(int_x, int_y) const;

};

Можно также создавать константные объекты. Для этого их объявления предваряют модификатором const. Например,

const Coord ob(3,5);

Ключевое слово const информирует компилятор, что со­стояние данного объекта не должно изменяться. В связи с этим компилятор генерирует сообщение об ошибке, если для кон­стантного объекта вызывается функция-член (которая может изменить его данные-члены, изменив тем самым его состоя­ние). Исключением из этого правила являются константные функции-члены, которые в силу своего определения не изме­няют состояние объекта. Приведем пример:

class Coord

{

int х, у;

public:

Coord(int _x, int _y);

void SetVal(int _x, int _y);

void GetVal(int &_x, int &_y) const;

};

Coord::Coord(int _x, int _y)

{

x = _x;

у = _y;

}

void

Coord::SetVal(int _x, int _y)

{

x = _x;

у = _y;

}

//Константная функция-член

void

Coord::GetVal(int &_x, int &_y) const

{

_x = x;

_y = y;

}

int main()

{

Coord ptl(3,8);

const Coord pt(6,9) ; //Константный объект

int x, у;

ptl.GetVal(x,y);

//Ошибка.. Вызов не-константной функция-члена

pt2. SetVal (x, у);

pt2.GetVal(x, у);

return 0;

}

Чтобы обойти указанные выше ограничения на использование константных функций-членов класса, в стандарт языка C++ было введено новое ключевое слово mutable. Это ключевое слово позволяет указать, какие данные-члены класса могут быть моди­фицированы константными функциями-членами. Ключевое слово mutable нельзя использовать для статических и константных членов-данных; оно используется как модификатор типа, то есть синтаксис его использования имеет вид:

mutable <тип_данных> <имя_переменной-члена>;

Приведем пример использования ключевого слова mutable:

#include <iostream.h>

class AnyClass

{

mutable int count;

mutable const int* iptr;

public:

int func(int i=0) const

{

count = i++;

iptr = &i;

cout « iptr;

return count;

}

};

Здесь в операторе

mutable const int* iptr;

модификатор mutable допустим, так как iptr является указа­телем на целое число, которое есть константа, хотя сам указатель константой не является.

Соседние файлы в папке ЯзыкС++Глушаков