Чтение онлайн

ЖАНРЫ

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

Либерти Джесс

Шрифт:

В данном случае использование оператора new вызывает конструктор класса по умолчанию, т.е. конструктор, использующийся без параметров. Важно помнить, что при создании объекта класса конструктор вызывается всегда, независимо от того, размещается объект в стеке или в области динамического обмена.

Удаление объектов

При использовании оператора delete, за которым следует идентификатор указателя на объект, вызывается деструктор соответствующего класса. Это происходит еще до освобождения памяти и возвращения

ее в область динамического обмена. В деструкторе, как правило, освобождается вся память, занимаемая объектом класса. Пример динамического размещения и удаления объектов показан в листинге 8.5.

Листинг 8.5. Размещение и удаление объектов в области динамического обмена

1: // Листинг 8.5.

2: // Размещение и удаление объектов в области динамического обмена

3:

4: #include <iostream.h>

5:

6: class SimpleCat

7: {

8: public:

9: SimpleCat;

10: ~SimpleCat;

11: private:

12: int itsAge;

13: };

14:

15: SimpleCat::SimpleCat

16: {

17: cout << "Constructor called.\n";

18: itsAge = 1;

19: }

20:

21: SimpleCat::~SimpleCat

22: {

23: cout << "Destructor called.\n";

24: }

25:

26: int main

27: {

28: cout << "SimpleCat Frisky...\n";

29: SimpleCat Frisky;

30: cout << "SimpleCat *pRags = new SimpleCat...\n";

31: SimpleCat * pRags = new SimpleCat;

32: cout << "delete pRags...\n";

33: delete pRags;

34: cout << "Exiting, watch Frisky go...\n";

35: return 0;

36: }

Результат:

SimpleCat Frisky...

Constructor called.

SimpleCat *pRags = new SimpleCat..

Constructor called.

delete pRags...

Destructor called.

Exiting, watch Frisky go...

Destructor called.

Анализ: В строках 6—13 приведено описанИе простейшего класса SimpleCat. Описание конструктора класса находится в строке 9, а его тело — в строках 15-19. Деструктор описан в строке 10, его тело — в строках 21-24.

В строке 29 создается экземпляр описанного класса, который размешается в стеке. При этом происходит неявный вызов конструктора класса SimpleCat. Второй объект класса создается в строке 31. Для его хранения динамически выделяется память и адрес записывается в указатель pRags. В этом случае также вызывается конструктор. Деструктор класса SimpleCat вызывается в строке 33 как результат применения оператора delete к указателю pRags. При выходе из функции переменная Frisky оказывается за пределами области видимости и для нее также вызывается деструктор.

Доступ к членам класса

Для локальных переменных, являющихся объектами класса, доступ к членам класса осуществляется с помощью оператора прямого доступа (.). Для экземпляров класса, созданных динамически, оператор прямого доступа применяется для объектов, полученных разыменованием указателя. Например, для вызова функции-члена GetAge нужно написать:

(*pRags).GetAge;

Скобки указывают

на то, что оператор разыменования должен выполняться еще до вызова функции GetAge.

Такая конструкция может оказаться достаточно громоздкой. Решить эту проблему позволяет специальный оператор косвенного обращения к члену класса, по написанию напоминающий стрелку (->). Для набора этого оператора используется непрерывная последовательность двух символов: тире и знака "больше". В C++ эти символы рассматриваются как один оператор. Листинг 8.6 иллюстрирует пример обращения к переменным и функциям класса, экземпляр которого размещен в области динамического обмена.

Листинг 8.6. Доступ к данным объекта в области динамического обмена

1: // Листинг 8.6.

2: // Доступ к данным объекта в области динамического обмена

3:

4: #include <iostream.h>

5:

6: class SimpleCat

7: {

8: public:

9: SimpleCat { itsAge = 2; }

10: ~SimpleCat { }

11: int GetAge const { return itsAge; >

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

13: private:

14: int itsAge;

15: };

16:

17: int main

18: {

19: SimpleCat * Frisky = new SimpleCat;

20: cout << "Frisky " << Frisky->GetAge << " years old\n";

21: Frisky->SetAge(5);

22: cout << "Frisky " << Frisky->GetAge << " years old\n";

23: delete Frisky;

24: return 0;

25: }

Результат:

Frisky 2 years old

Frisky 5 years old

Анализ: В строке 19 в области динамического обмена выделяется память для хранения экземпляра класса SimpleCat. Конструктор, вызываемый по умолчанию, присваивает новому объекту возраст два года. Это значение получено как результат выполнения функции-члена GetAge, которая вызывается в строке 20. Поскольку мы имеем дело с указателем на объект, для вызова функции используется оператор косвенного обращения к члену класса (->). В строке 21 для установки нового значения возраста вызывается метод SetAge, а повторный вызов функции GetAge (строка 22) позволяет получить это значение.

Динамическое размещение членов класса

В качестве членов класса могут выступать и указатели на объекты, размещенные в области динамического обмена. В таких случаях выделение памяти для хранения этих объектов осуществляется в конструкторе или в одном из методов класса. Освобождение памяти происходит, как правило, в деструкторе (листинг 8.7.).

Листинг 8.7. Указатели как члены класса

1: // Листинг 8.7.

2: // Указатели как члены класса

3:

4: #include <iostream.h>

5:

6: class SimpleCat

7: {

8: public:

9: SimpleCat;

10: ~SimpleCat;

11: int GetAge const { return *itsAge; }

12: void SetAge(int age) { *itsAge = age; }

13:

14: int GetWeight const { return *itsWeight; }

15: void setWeight (int weight) { *itsWeight = weight; }

16:

17: private:

18: int * itsAge:

19: int * itsWeight;

20: };

Поделиться с друзьями: