Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методические указания.doc
Скачиваний:
9
Добавлен:
18.04.2015
Размер:
619.52 Кб
Скачать

Виды памяти и создание объектов

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

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

Стек используется для передачи параметров в методы и для создания внутренних переменных методов, существующих только во время выполнения метода или его части. Создание переменных в сетке встраивается в объектный код программы компилятором и происходит прозрачно для программиста. Обращение программиста к переменным метода компилятор преобразует в обращение к стеку по фиксированному смещению от вершины (вглубь стека).

При вызове метода ее параметры помещаются на вершину стека. Если в методе объявлены другие переменные, то они также помещаются на вершину стека. В момент компиляции команды с обращением к той или иной переменной компилятор вычисляет по какому смещению располагается эта переменная относительно вершины стека и встраивает в объектный код программы ссылку на позицию в стеке по фиксированному смещению от вершины. При завершении работы метода или вложенного блока операторов, все переменные, объявленные в этом методе (или блоке), снимаются с вершины стека. Например, если в программе объявлены следующие функции:

void methodA (int x, float y)

{

int c;

methodB (x, y, c);

… -- Точка X

}

void methodB (int x, float y, int d)

{

int c;

… -- Точка Y

}

то в точке Y в стеке будут существовать следующие переменные:

А в точке X следующие:

Использование кучи зависит от языка программирования. Например, в C++ создание переменных в куче полностью управляется программистом. После создания переменной программисту доступен указатель на ее начало. За удаление переменной в конце ее жизненного цикла отвечает сам программист, что служит причиной большого количества ошибок, приводящих к утечке памяти. В Java, наоборот, использование кучи прозрачно для программиста: если переменная представляет собой сложный объект, то она автоматически размещается в куче. Когда последняя ссылка на такой объект удаляется, он помечается неиспользуемым. В Java-машине существует регулярный процесс, называемый сборщиком мусора, который и отвечает за освобождение памяти из-под неиспользуемых объектов.

Если переменная представляет собой сложный объект, то во время ее создания вызывается конструктор, а во время уничтожения – деструктор, где бы она не находилась: в сегменте данных, в стеке или в куче.

Управление доступом к переменным и методам класса

Для переменных и методов класса может быть задан уровень доступа, регламентирующий доступ к переменным и методам одного класса из методов другого класса. Наиболее жестким является личный уровень доступа, дающий разрешение на доступ к переменным и методам только для методов самого класса. Наименее жестким – общий уровень доступа, дающий разрешение на доступ из любой точки программы. Средним вариантом является личный защищенный уровень доступа, когда доступ разрешен только для методов самого класса и его наследников. Уровень доступа в классе-потомке к переменной или методу класса-предка может быть изменен в сторону ужесточения. В зависимости от языка программирования промежуточные уровни доступа могут различаться. Так, например, в Java существует два дополнительных уровня доступа. В случае нарушения программистом регламента доступа к переменным во время компиляции программы будет выдано сообщение об ошибке. Приведем пример задания уровней доступа для переменных класса на языке C++:

class Person {

private: -- Личный уровень доступа

int number; -- Индивидуальный номер человека

public: -- Общий уровень доступа

char name[10]; -- Имя

protected: -- Личный защищенный уровень доступа

int age; -- Возраст

float height; -- Рост

};

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

class B {

friend class A; -- Объявление дружественного класса.

};

Второй механизм позволяет объявлять лишь некоторые методы класса A как дружественные классу B. Это приводит к возможности обращаться ко всем переменным и методам класса B, независимо от заданного для них уровня доступа, только в рамках этих методов. Например,

class B {

friend A::methodX; -- Объявление дружественного метода

};