Рейтинговые книги
Читем онлайн Освой самостоятельно С++ за 21 день. - Джесс Либерти

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 87 88 89 90 91 92 93 94 95 ... 170

24:    int i; Cat *CatHouse[MaxCats];

25:    for (i = 0; i<MaxCats; i++)

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

27:

28:    for (i = 0; i<MaxCats; 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 oldn";

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 <iostream.h>

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<MaxCats; i++)

28:    {

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

30:       TelepathicFunction();

31:    }

32:

33:    for ( i = 0; i<MaxCats; 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 <iostream.h>

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<MaxCats; i++)

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

28:

29:    for (i = 0; i<MaxCats; 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 oldn";

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.

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

Статические функции-члены

Статические функции-члены подобны статическим переменным-членам: они не принадлежат одному объекту, а находятся в области видимости всего класса. Именно поэтому их можно вызывать даже в тех случаях, когда не было создано ни одного объекта класса, как показано в листинге 14.4.

Листинг 14.4. Статические функции-члены

1: // Листинг 14.4. Статические функции-члены

2:

3: #include <iostream.h>

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 GetHowMany() { return HowManyCats; }

13:   private:

14:      int itsAge;

15:      static int HowManyCats;

16: };

17:

18: int Cat::HowManyCats = 0;

19:

20: void TelepathicFunction();

21:

22: int main()

23: {

24:    const int MaxCats = 5;

25:    Cat *CatHouse[MaxCats]; int i;

26:    for (i = 0; i<MaxCats; i++)

27:    {

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

29:       TelepathicFunction();

30:    }

31:

32:    for ( i = 0; i<MaxCats; i++),

33:    {

34:       delete CatHouse[i];

35:       TelepathicFunction();

36:    }

37:    return 0;

1 ... 87 88 89 90 91 92 93 94 95 ... 170
На этой странице вы можете бесплатно читать книгу Освой самостоятельно С++ за 21 день. - Джесс Либерти бесплатно.

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