Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Data Structures and Algorithms in C++ 2e (На ру...docx
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
2.37 Mб
Скачать

1.5. Классы 41

Декларация объекта призывание векторного конструктора, который ассигнует

множество 100 целых чисел и a.data указывает на это множество. Декларация «Vect b=a» инициализирует b от a. Так как мы не предоставили конструктору копии в Vect, система использует свой неплатеж, который просто копирует каждого члена к b. В особенности это устанавливает «b.data=a.data». Заметьте, что это не копирует содержание множества; скорее это копирует указатель на начальный элемент множества. Это действие по умолчанию иногда называют мелкой копией.

Декларация c призывает конструктора с ценностью аргумента по умолчанию 10, и следовательно ассигнует множество 10 элементов в свободном магазине. Поскольку мы не предоставили оператору назначения, заявление «c=a», также делает мелкую копию к c. Только указатели скопированы, не выстраивают содержание. Хуже все же, мы потеряли указатель на оригинальное множество c с 10 элементами, таким образом создав утечку памяти.

Теперь, a, b, и c у всех есть участники, которые указывают на то же самое множество в свободном магазине. Если бы содержание множеств одного из этих трех должно было измениться, другие два загадочно изменились бы также. Хуже все же, если один из этих трех должен был быть удален перед другими (например, если бы эта переменная была объявлена во вложенном блоке), печь для сжигания отходов производства удалила бы общее множество. Когда любая из других двух попыток получить доступ к теперь удаленному множеству, результаты имели бы катастрофические последствия. Короче говоря, здесь есть много проблем.

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

Vect:: Vect (константа Vect& a)

размер = a.size;

данные = новый интервал [размер];

для (интервал i = 0; я <размер; я ++)

данные [я] = a.data [я];

//

// // //

скопируйте конструктора с a

размеры копии ассигнуют новую копию множества векторное содержание

Оператор назначения обработан, перегрузив = оператор как показано в следующем кодовом фрагменте. Аргумент «a» играет роль объекта на правой стороне оператора назначения. Оператор назначения удаляет существующее хранение множества, ассигнует новое множество надлежащего размера и копирует элементы в это новое множество. Если заявление проверяет против возможности сам назначение. (Это может иногда происходить, когда различные переменные ссылаются на тот же самый объект.) Мы выполняем эту проверку, используя ключевое слово это. Для любого случая объекта класса,

42

Помнить

Глава 1. C ++ Учебник для начинающих «это» определено, чтобы быть адресом этого случая. Если это равняется адресу a, то это - случай сам назначение, и мы игнорируем операцию. Иначе, мы освобождаем существующее множество, ассигнуем новое множество и копируем содержание.

Vect& Vect:: оператор = (константа Vect& a)

//

оператор назначения от a

если (это! = &a)

//

избегите самоназначения

удалите [] данные;

//

удалите старое множество

размер = a.size;

//

установите новый размер

данные = новый интервал [размер];

//

ассигнуйте новое множество

для (интервал i=0; я <размер; я ++)

//

скопируйте векторное содержание

данные [я] = a.data [я];

возвратитесь *это;

Заметьте, что в последней линии оператора назначения мы возвращаем ссылку на текущий объект с заявлением «возвращение *это». Такой подход полезен для операторов назначения, так как он позволяет нам цепи вместе назначения, как в «a=b=c». Назначение «b=c» призывает оператора назначения, копируя vari-способный c к b и затем возвращает ссылку на b. Этот результат тогда назначен на переменную a.

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

Каждый класс, который ассигнует его собственные объекты, использующие новый, должен:

• Определите печь для сжигания отходов производства, чтобы освободить любые ассигнованные объекты.

• Определите конструктора копии, который ассигнует ее собственного нового участника stor-

возраст и копии содержание членских переменных.

• Определите оператора назначения, который освобождает старое хранение, allo-

киты новое хранение и копии все членские переменные.

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