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

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

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

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: };

21:

22: SimpleCat::SimpleCat

23: {

24:    itsAge = new int(2);

25:    itsWeight = new int(5);

26: }

27:

28: SimpleCat::~SimpleCat

29: {

30:    delete itsAge;

31:    delete itsWeight;

32: }

33:

34: int main

35: {

36:    SimpleCat *Frisky = new SimpleCat;

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

38:    Frisky->SetAge(5);

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

40:    delete Frisky;

41:    return 0;

42: }


Результат:

Frisky 2 years old

Frisky 5 years old


Анализ: Объявляем класс, переменными-членами которого являются два указателя на тип int. В конструкторе класса (строки 22—26) выделяется память для хранения этих переменных, а затем им присваиваются начальные значения.

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

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

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

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

Дональд Бокс

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