Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
21-34_ПР-ИЕ.doc
Скачиваний:
13
Добавлен:
28.08.2019
Размер:
328.19 Кб
Скачать

29. Указатели и динамическое распределение памяти. Понятие указателя. Виды указателей. Динамическое и статическое распределение памяти. Разадресация и разыменование. Проблемы использования указателей.

Указатели — это особый вид объектов, предназначенный для хранения информации о местоположении в памяти других объектов. Значением объекта-указателя является адрес другого объекта. Под адресом понимается номер ячейки оперативной памяти. Особое место во множестве значений указателей занимает "пустой адрес" - Nil. («пустой адрес» означает, что это значение указателя не указывает ни на один из существующих в программе объектов). Считается, что если указатель равен Nil, то переменная, на которую он указывает отсутствует в ОП (соответственно, ее нельзя оттуда удалить). Указатели (в реальном режиме IBM PC) могут принимать значения от 0000:0000 до FFFF:FFFF, то есть могут обеспечить доступ к любой ячейке оперативной памяти.

Объекты-указатели, равно как и любые другие объекты, размещаются в памяти, занимая в ней определённое количество ячеек. Поскольку объект-указатель хранит адрес другого объекта, а адрес — это номер ячейки памяти, то, независимо от типа (а, следовательно, и размера) объекта, на который указывает объект-указатель, сам объект-указатель занимает в памяти 4 ячейки — 4 байта, для 32-разрядной адресации 64-битных системах адрес занимает 8 байт.

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

С указателями могут выполняться следующие операции: разадресация - получение адреса объекта в памяти, присваивание, сложение с константой, вычитание, инкремент (+ +) , декремент (- -), сравнение (равенство «=» и неравенство «<>», других сравнений не допускается), приведение типов. При работе с указателями часто используется операция получения адреса. Операция разыменование - получение доступа к объекту через указатель, предназначена для доступа к величине, адрес которой хранится в указателе. Эту операцию можно использовать как для получения, так и для изменения значения величины (если она не объявлена как константа). Арифметические операции с указателями (сложение с константой, вычитание, инкремент и декремент) применимы только к указателям одного типа и имеют смысл в основном при работе со структурами данных, последовательно размещенных в памяти, например с массивами. Инкремент перемещает указатель к следующему элементу массива, декремент — к предыдущему.

Статическая память — это область памяти, выделяемая при запуске программы из свободной оперативной памяти.

Динамическая память — это совокупность блоков памяти, выделяемых из доступной свободной оперативной памяти непосредственно во время выполнения программы.

При использовании указателей допускаются следующие общие ошибки:

- разыменование неинициализированных указателей;

- потери динамически распределяемой памяти ("утечки").

Разыменование неинициализированных указателей

Одним из общих источников ошибок при работе с указателями является разыменование указателя, который еще не был инициализирован. Значение переменной-указателя не будет определено, пока вы не присвоите ей значение, так что она сможет указывать на какой-то адрес в памяти.

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

операционную систему.

Потери динамически распределяемой памяти ("утечки").

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

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

30. Основные концепции объектно-ориентированного программирования. Инкапсуляция, наследование и полиморфизм. Класс, члены класса, объект класса, элементы и методы объекта класса. Основные формы полиморфизма в C++.

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

Языки поддерживающие ООП имеют как минимум 3 характерные(основные) черты:

  1. Поддерживают полиморфизм.

  2. Для них характерна инкапсуляция.

  3. Поддерживают механизм наследования.

Один из центральных элементов ООП - абстракция.

Абстракция в ООП позволяет смотреть на объект, не требуя разобраться в той совокупности сложных частей, из которых данный объект состоит. Через абстракцию человек управляет сложностью представления объектов, выделяя только интересующие его свойства объекта.

ООП характеризуется следующими принципами (по Алану Кею):

- все является объектом;

- вычисления осуществляются путем взаимодействия (обмена данными) между объектами, при котором один объект требует, чтобы другой объект выполнил некоторое действие; -

- объекты взаимодействуют, посылая и получая сообщения; сообщение - это запрос на выполнение действия, дополненный набором аргументов, которые могут понадобиться при выполнении действия;

- каждый объект имеет независимую память, которая состоит из других объектов;

- каждый объект является представителем класса, который выражает общие свойства объектов данного типа;

- в классе задается функциональность (поведение объекта); тем самым все объекты, которые являются экземплярами одного класса, могут выполнять одни и те же действия;

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

Инкапсуляция — свойство языка программирования, позволяющее объединить и защитить данные и код в объектe и скрыть реализацию объекта от пользователя (под пользователем здесь понимается программист (разработчик), использующий класс при создании программ). При этом пользователю предоставляется только интерфейс объекта.

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

Полиморфизм - это свойство, которое позволяет одно и то же имя использовать для решения двух или более схожих, но технически разных задач. Целью полиморфизма, является использование одного имени для задания общих для класса действий. Основные формы полиморфизма в С++:

- динамический, когда вызываемая функция определяется во время выполнения (поздний полиморфизм );

- статический, когда вызываемая функция определяется в процессе компиляции (ранний полиморфизм ).

Класс - в программировании – обобщенный пользовательский тип данных, объединяющий описание набора данных (свойств) и функций - методов обработки этих данных.

Члены класса. Поле. Так называется член-переменная, содержащий некоторое значение. В ООП поля иногда называют данными объекта. К полю можно применять несколько модификаторов в зависимости от того, как вы собираетесь это поле использовать. В число модификаторов входят static, readonly и const.

Метод. Это реальный код, воздействующий на данные объекта (или поля). Свойства. Их иногда называют "разумными" полями, так как они на самом деле являются методами, которые клиенты класса воспринимают как поля. Константы. Константа — это поле, значение которого изменить нельзя. Операторы. Используя перегрузку операторов С#, можно добавлять к классу стандартные математические операторы, которые позволяют писать более интуитивно понятный код.

Объект — это экземпляр класса. Объект содержит данные, называемые элементами объекта. Для обработки этих данных, применятся подпрограммы, называемые методами объекта. Элементы объекта иногда называют свойствам объекта. Объекты, входящие в класс называют его объектами-членами. Функции, входящие в класс называются его функциями-членами. Объекты – члены и функции-члены вместе называются члены класса.