Скачиваний:
316
Добавлен:
28.03.2021
Размер:
378.53 Кб
Скачать

24. Создание, особенности использование конструктора копии при передаче объекта в качестве параметра функции, возврате объекта из функции и инициализации объектов.

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

Конструктор копирования вызывается в случаях, когда нужно получить полную копию объекта. В C++ полная копия объекта нужна в трех случаях.

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

Случай 2. Когда нужно передать объект в функцию как параметр-значение. В этом случае создается полная копия объекта.

Случай 3. Когда нужно вернуть объект из функции по значению. В этом случае также создается полная копия объекта.

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

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

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

Особенности:

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

  • Конструктор копии также вызывается в случае, когда один объект используется для инициализации другого. Использование конструктора копии гарантирует, что объект b выделит для своих членов данных собственную область памяти. Без конструктора копии объект b попросту представлял бы собой точную копию объекта а, а член а.р указывал бы на ту же самую область памяти, что и член b.р

  • Конструктор копии также вызывается при создании временного объекта, который является результатом возвращения функцией объекта.

25. Локальные static-переменные. Глобальные static-переменные.

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

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

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

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

Имена статических локальных переменных известны только функции или блоку кода, в которых они объявлены, а имена статических глобальных переменных известны только в файле, в котором они находятся. В сущности модификатор static разрешает использование функциями переменных, не беспокоя другие функции.

Статические переменные позволяют прятать части программы. Это может привести к большим преимуществам при разработке больших и сложных программ.

26. Особенности выделения памяти при работе с классами и объектами. Статические компоненты класса. Применение статических полей класса. Раздельное объявление и определение статических полей класса. Применение статических методов класса.

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

Поскольку переменная является указателем на объект, для доступа к его членам используется оператор ->. Как известно, динамические объекты могут содержать конструкторы и деструктор. Кроме того, конструкторы могут иметь параметры.

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

Для уничтожения массива динамических объектов следует применять оператор delete[ ], чтобы можно было вызывать деструктор для каждого объекта отдельно.

Каждый объект класса имеет собственную копию данных, определенных в этом классе.

Статические данные относятся ко всем объектам класса. Такие данные используются, если

  • требуется контроль общего количества объектов класса;

  • требуется одновременный доступ ко всем объектам или части их;

  • требуется разделение объектами общих ресурсов.

В этом случае в определение класса могут быть введены статические члены.

Статические член-данные (или поля) класса можно рассматривать как глобальную переменную класса. Но в отличие от обычных глобальных переменных на статические члены распространяются правила видимости private и public. Поместив статическую переменную в часть private, можно ограничить ее использование.

Статические поля нельзя инициализировать в теле класса, а также в методах. Статические поля должны инициализироваться аналогично глобальным переменным в области видимости файла.

Если поле данных описано с static, то значение этого поля будет одинаковым для всех объектов этого класса. Статические поля класса не копируются для каждого объекта отдельно. Статические поля видимы только внутри класса, но время жизни совпадает с временем жизни приложения. Статические поля сущ в 1 экземпляре, даже если не сущ ни одного объекта класса.

Статические переменные инициализируются ещё до создания объекта. Статические переменные исп для экономии памяти, когда достаточно только 1 копии данных для всего набора объектов.

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

Метод класса может быть объявлен как статический, если он обращается к статическим элементам класса. Статические методы могут обращаться только к статическим полям и вызывать только другие статические методы. Статическим методам не передается указатель this. Статические методы не могут быть const, virtual, volаtile. Один и тот же метод не может быть одновременно статическим и не статическим. Обращение к статическим методам происходит через имя класса или объекта. Статические методы применяются для предварительной инициализации закрытых статических полей до создания реальных объектов