Читаем Освой самостоятельно С++ за 21 день. полностью

25:    for (i = 0; i

26:       CatHouse[i] = new Cat(i);

27:

28:    for (i = 0; i

29:    {

30:       cout << "There are ";

31:       cout << Cat::HowManyCats;

32:       cout << " cats left!\n";

33:       cout << "Deleting the one which is ";

34:       cout << CatHouse[i]->GetAge;

35:       cout << " yea.rs old\n";

36:       delete CatHouse[i];

37:       CatHouse[i] = 0;

38:    }

39:    return 0;

40: }


Результат:

There are 5 cats left!

Deleting the one which is 0 years old

There are 4 cats left!

Deleting the one which is 1 years old

There are 3 cats left!

Deleting the one which is 2 years old

There are 2 cats left!

Deleting the one which is 3 years old

There are 1 cats left!

Deleting the one which is 4 years old


Анализ: Обычный класс Cat объявляется в строках 5—17. С помощью ключевого слова static в строке 12 объявляется статическая переменная-член

HowManyCats типа int.

Объявление статической переменной HowManyCats само по себе не определяет никакого целочисленного значения, т.е. в памяти компьютера не резервируется область для данной переменной при ее объявлении, поскольку, по сути, она не является переменной-членом конкретного объекта Cat. Определение и инициализация переменной HowManyCats происходит в строке 19.

Не забывайте отдельно определять статическую переменную-член класса (весьма распространенная ошибка среди начинающих программистов). В противном случае редактор связей во время компиляции программы выдаст следующее сообщение об ошибке:

undefined symbol Cat::HowManyCats

Обратите внимание, что для обычной переменной-члена itsAge не требуется отдельное определение, поскольку обычные переменные-члены определяются автоматически каждый раз при создании объекта Cat, как, например, в строке 26.

Конструктор объекта Cat, объявленный в строке 8, увеличивает значение статической переменной-члена на единицу. Деструктор, объявленный в строке 9, уменьшает это значение на 1. Таким образом, в любой момент времени переменная HowManyCats отражает текущее количество созданных объектов класса Cat.

В строках программы 21—40 создается пять объектов Cat, указатели на которые заносятся в массив. Это сопровождается пятью вызовами конструктора класса Cat, в результате чего пять раз происходит приращение на единицу переменной HowManyCats, начиная с исходного значения 0.

Затем в программе цикл for последовательно удаляет все объекты Cat из массива, предварительно выводя на экран текущее значение переменной HowManyCats. Вывод начинается со значения 5 (ведь было создано пять объектов) и с каждым циклом уменьшается.

Обратите внимание: переменная HowManyCats объявлена как public и может вызываться из функции main. Однако нет веских причин объявлять эту переменную-член таким образом. Если предполагается обращаться к статической переменной только через объекты класса Cat, предпочтительней сделать ее закрытой вместе с другими переменными-членами и создать открытый метод доступа. С другой стороны, если необходимо получать прямой доступ к данным без использования объекта Cat, то можно либо оставить ее открытой, как показано в листинге 14.2, либо создать статическую функцию-член. Реализация последнего варианта рассматривается далее в этой главе.

Листинг 14.2. Доступ к статическим членам без использования объектов 

1: // Листинг 14.2. Статические переменные-члены

2:

3: #include

4:

5: class Cat

6: {

7:    public:

8:       Cat(int age):itsAge(age) { HowManyCats++; }

9:       virtual ~Cat { HowManyCats--; }

10:      virtual int GetAge { return itsAge; }

11:      virtual void SetAge(int age) {itsAge = age;}

12:      static int HowManyCats;

13:

14:   private:

15:      int itsAge;

16:

17: };

18:

19: int Cat::HowManyCats = 0;

20:

21: voidTelepathicFunction;

22:

23: int main

24: {

25:    const int MaxCats = 5; int i;

26:    Cat *CatHouse[MaxCats];

27:    for (i = 0; i

28:    {

29:       CatHouse[i] = new Cat(i);

30:       TelepathicFunction;

31:    }

32:

33:    for ( i = 0; i

34:    {

35:       delete CatHouse[i];

36:       TelepathicFunction;

37:    }

38:    return 0;

39: }

40:

41: void TelepathicFunction

42: {

43:    cout << "There are ";

44:    cout << Cat::HowManyCats << " cats alive!\n";

45: }


Результат:

There are 1 cats alive!

There are 2 cats alive!

There are 3 cats alive!

There are 4 cats alive!

There are 5 cats alive!

There are 4 cats alive!

There are 3 cats alive!

There are 2 cats alive!

There are 1 cats alive!

There are 0 cats alive!


Анализ: Листинг 14.2 аналогичен листингу 14.1, однако включает новую функцию TelepahicFunction.Она не создает объект СаГ и даже не использует тегов качестве параметра, однако может получить доступ к переменной-члену HowManyCats. Не лишним будет еще раз напомнить, что эта переменная-член относится не к какому-либо определенному объекту, а ко всему классу в целом. Поэтому если она объявлена как public, то может использоваться любой функцией программы.

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

Листинг 14.3. Доступ к статическим членам с помощью обычных функций-членов

1: //Листинг 14.3. Закрытые статические переменные-члены

2:

3: #include

4:

5: class Cat

6: {

7:    public:

8:       Cat(int age):itsAge(age){ HowManyCats++; }

9:       virtual ~Cat { HowManyCats--; }

10:      virtual int GetAge { return itsAge; }

11:      virtual void SetAge(int age) { itsAge = age; }

12:      virtual int GetHowMany { return HowManyCats; }

13:

14:

15:   private:

16:      int itsAge;

17:      static int HowManyCats;

18: };

19:

20: int Cat::HowManyCats = 0;

21:

22: int main

23: {

24:    const int MaxCats = 5; int i;

25:    Cat *CatHouse[MaxCats];

26:    for (i = 0; i

27:       CatHouse[i] = new Cat(i);

28:

29:    for (i = 0; i

30:    {

31:       cout << "There are ";

32:       cout << CatHouse[i]->GetHowMany;

33:       cout << " cats left!\n";

34:       cout << "Deleting the one which is ";

35:       cout << CatHouse[i]->GetAge+2;

36:       cout << " years old\n";

37:       delete CatHouse[i];

38:       CatHouse[i] = 0;

39:    }

40:    return 0;

41: }


Результат:

There are 5 cats left!

Deleting the one which is 2 years old

There are 4 cats left!

Deleting the one which is 3 years old

There are 3 cats left!

Deleting the one which is 4 years old

There are 2 cats left!

Deleting the one which is 5 years old

There are 1 cats left!

Deleting the one which is 6 years old


Анализ: В строке 17 статическая переменная-член HowManyCats объявлена как private. Поэтому теперь доступ к ней закрыт для функций, не являющихся членами класса, например для функции TelepathicFunction из предыдущего листинга.

Хотя переменная HowManyCats является статической, она все же находится в области видимости класса. Поэтому любая функция класса, например GetHoqMany, может получить доступ к ней так же, как к любой обычной переменной-члену. Однако для вызова GetHowMany функция должна иметь объект, через который осуществляется вызов.


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


Не рекомендуется:Не используйте статические перемен- ные-члены для хранения данных одного объекта. Эти переменные предназначены для обмена данными между объектами.

Перейти на страницу:

Похожие книги

Сущность технологии СОМ. Библиотека программиста
Сущность технологии СОМ. Библиотека программиста

В этой книге СОМ исследуется с точки зрения разработчика C++. Написанная ведущим специалистом по модели компонентных объектов СОМ, она раскрывает сущность СОМ, помогая разработчикам правильно понять не только методы модели программирования СОМ, но и ее основу. Понимание мотивов создания СОМ и ее аспектов, касающихся распределенных систем, чрезвычайно важно для тех разработчиков, которые желают пойти дальше простейших приложений СОМ и стать по-настоящему эффективными СОМ-программистами. Показывая, почему СОМ для распределенных систем (Distributed СОМ) работает именно так, а не иначе, Дон Бокс дает вам возможность применять эту модель творчески и эффективно для ежедневных задач программирования.

Дональд Бокс

Программирование, программы, базы данных / Программирование / Книги по IT