Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






Листинг 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: };

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) выделяется память для хранения этих переменных, а затем им присваиваются начальные значения.

Выделенная под переменные-члены память освобождается в деструкторе (строки 28—32). После освобождения памяти в деструкторе присваивать указателям нулевые значения не имеет смысла, поскольку уничтожается и сам экземпляр класса. Такая ситуация является одним из тех случаев, когда после освобождения памяти указателю можно не присваивать значение 0.

При выполнении функции, из которой осуществляется обращение к переменным класса (в данном случае main()), вы можете и не знать, каким образом выполняется это обращение. Вы лишь вызываете соответствующие методы класса (GetAge() и SetAge()), а все операции с памятью выполняются внутренними механизмами класса.

При уничтожении объекта Frisky (строка 40) вызывается деструктор класса SimpleCat. В деструкторе память, выделенная под члены класса, освобождается. Если один из членов класса является объектом другого определенного пользователем класса, происходит вызов деструктора этого класса.

 

Вопросы и ответы: Если я объявляю объекг класса, хранящийся в стеке, а этот объект, в свою очередь, имеет переменные-члены, хранящиеся в области динамического обмена, то какие части объекта будрт находиться в стеке, а какие — в области динамического обмена?

#include < iostream.h>

class SimpleCat

{

public:

SimpleCat();

~SimpleCat();

int GetAge() const { return *itsAge; }

// другие методы

private:

int * itsAge;

int * itsWeight;

};

SimpleCat:: SimpleCat()

{

itsAge = new int(2);

itsWeight = new int(5);

}

SimpleCat:: ~SimpleCat()

{

delete itsAge;

delete itsWeight;

}

int main()

{

SimpleCat Frisky;

cout < < " Frisky is " < < Frisky.GetAge() < < " years old\n";

return 0;

}

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

 

Конечно, для данного примера динамическое размещение в памяти переменных- членов не обязательно. Однако в реальных программах такой способ хранения данных может оказаться достаточно эффективным.

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

Допустим, первым объектом является окно, а вторым — документ. Вполне понятно, что окно должно иметь доступ к документу. С другой стороны, продолжительность существования документа никак не контролируется окном. Поэтому для окна важно хранить лишь ссылку на этот документ.

Об использовании ссылок речь идет на затянии 9.

 






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.