Студопедия

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

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

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






Конструктор и операция new






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

class String {

char * str;

int row, col; public:

//Конструктор:

String ();

//Деструктор:

~StringO {delete str; }

};

void main() {

//Создание объекта типа String:

String* ptr = new String;

//...

}

Если же конструктор класса имеет аргументы, то список фактических аргументов помещается там, где при работе со стандартными типами данных находится инициализирующее выражение:

class String

{

char * str;

int row, col; public:

//Конструктор:

String (char*);

//Деструктор:

~String() {delete str; } };

void main() {

//Создание объекта типа String:

String* ptr = new String(" Строка");

}

В случае с классами под именем типа понимается имя конструктора (которое совпадает с именем типа), а под инициализирующим выражением - список фактических аргументов конструктора, то есть операция new в качестве своего операнда использует обращение к конструктору. Такая аналогия позволяет без труда ориентироваться в синтаксисе операции выделения памяти для объектов классов.

Если в операции new происходит обращение к конструктору без аргументов (неважно, является ли он конструктором по умолчанию или нет), то допустимы обе следующие формы записи:

String* ptrl = new String(); String* ptr2 = new String;

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

String* р = new String;

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

Если указатель относится к экземпляру класса (объекту), созданному динамически, то деструктор для него вызывается из операции delete.

Конструктор копирования – это конструктор, первым (и единственным) аргументом которого является ссылка на объект того класса, в котором этот конструктор объявлен.

То есть, в классе С объявление конструктора копирования имеет вид:

 

С (const C&);

 

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

§ при инициализации одного объекта другим;

§ при передаче объекта по значению в функцию;

§ при возврате объекта из функции по значению.

(В последних двух случаях, как мы знаем, создаётся временная копия объекта в стеке.)

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

Когда следует явно определять конструктор копирования? Следует учесть, что сгенерированный компилятором конструктор копирования может создать только точную копию исходного объекта, т.е. выполнить поэлементное копирование, что требуется далеко не всегда. Недостатки такого копирования такие же, что и при присваивании. Таким образом, для объектов, содержащих указатели на динамически распределяемые участки памяти, следует явно определять в классе конструктор копирования.

 







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