C конструктор копирования вектора
Мы обсудили введение в конструкторы в C ++ . В этом посте обсуждается конструктор копирования.
Что такое конструктор копирования?
Конструктор копирования — это функция-член, которая инициализирует объект, используя другой объект того же класса. Конструктор копирования имеет следующий общий прототип функции:
Ниже приведен простой пример конструктора копирования.
using namespace std;
Point( int x1, int y1)
Point( const Point &p2)
Point p1(10, 15); // Здесь вызывается нормальный конструктор
Point p2 = p1; // Копируем конструктор здесь
// Давайте получим доступ к значениям, назначенным конструкторами
Когда вызывается конструктор копирования?
В C ++ конструктор копирования может вызываться в следующих случаях:
1. Когда объект класса возвращается по значению.
2. Когда объект класса передается (в функцию) по значению в качестве аргумента.
3. Когда объект строится на основе другого объекта того же класса.
4. Когда компилятор генерирует временный объект.
Когда нужен определяемый пользователем конструктор копирования?
Если мы не определяем наш собственный конструктор копирования, компилятор C ++ создает конструктор копирования по умолчанию для каждого класса, который выполняет поэлементное копирование между объектами. В общем, созданный компилятором конструктор копирования работает нормально. Нам нужно определять наш собственный конструктор копирования, только если у объекта есть указатели или какое-либо распределение ресурсов во время выполнения, например, дескриптор файла, сетевое соединение и т. Д.
Конструктор по умолчанию делает только поверхностное копирование.
Глубокое копирование возможно только с определенным пользователем конструктором копирования. В определяемом пользователем конструкторе копирования мы гарантируем, что указатели (или ссылки) копируемого объекта указывают на новые области памяти.
Конструктор копирования против Оператора присваивания
Какой из следующих двух операторов вызывает конструктор копирования, а какой — оператор присваивания?
MyClass t3 = t1; // ----> (1)
Конструктор копирования вызывается, когда новый объект создается из существующего объекта, как копия существующего объекта. Оператор присваивания вызывается, когда уже инициализированному объекту присваивается новое значение из другого существующего объекта. В приведенном выше примере (1) вызывает конструктор копирования и (2) вызывает оператор присваивания. Смотрите это для более подробной информации.
Написать пример класса, где нужен конструктор копирования?
Ниже приводится полная программа на C ++, демонстрирующая использование конструктора Copy. В следующем классе String мы должны написать конструктор копирования.
using namespace std;
String( const char *str = NULL); // конструктор
String( const String&); // копировать конструктор
void print() < cout // Функция для печати строки
void change( const char *); // Функция для изменения
String::String( const char *str)
size = strlen (str);
s = new char [size+1];
void String::change( const char *str)
size = strlen (str);
s = new char [size+1];
String::String( const String& old_str)
s = new char [size+1];
strcpy (s, old_str.s);
String str1( "GeeksQuiz" );
String str2 = str1;
str1.print(); // что напечатано?
str1.print(); // что печатается сейчас?
В чем будет проблема, если мы удалим конструктор копирования из кода выше?
Если мы удалим конструктор копирования из вышеуказанной программы, мы не получим ожидаемый результат. Изменения, внесенные в str2, отражаются и в str1, чего никогда не ожидается.
using namespace std;
String( const char *str = NULL); // конструктор
void change( const char *); // Функция для изменения
String::String( const char *str)
size = strlen (str);
s = new char [size+1];
void String::change( const char *str)
size = strlen (str);
s = new char [size+1];
String str1( "GeeksQuiz" );
String str2 = str1;
str1.print(); // что напечатано?
str1.print(); // что печатается сейчас?
Можем ли мы сделать конструктор копирования закрытым?
Да, конструктор копирования может быть закрытым. Когда мы делаем конструктор копирования закрытым для класса, объекты этого класса становятся недоступными для копирования. Это особенно полезно, когда у нашего класса есть указатели или динамически распределяемые ресурсы. В таких ситуациях мы можем либо написать собственный конструктор копирования, как в примере выше String, либо создать личный конструктор копирования, чтобы пользователи получали ошибки компилятора, а не сюрпризы во время выполнения.
Почему аргумент в конструктор копирования должен быть передан как ссылка?
Конструктор копирования вызывается, когда объект передается по значению. Сам конструктор копирования является функцией. Поэтому, если мы передадим аргумент по значению в конструкторе копирования, будет сделан вызов конструктора копирования, чтобы вызвать конструктор копирования, который становится цепочкой вызовов без завершения. Поэтому компилятор не позволяет передавать параметры по значению.
Пожалуйста, пишите комментарии, если вы обнаружите что-то неправильное или вы хотите поделиться дополнительной информацией по обсуждаемой выше теме.
В случае массивов, нет большого выбора для копирования массива в другой, кроме итеративного метода, то есть запуска цикла для копирования каждого элемента по соответствующему индексу. Но классы Vector имеют более одного метода для более простого копирования всего вектора в другой. В основном существует два типа копирования:
Способ 1: итерационный метод.
Этот метод является общим методом для копирования, в этом методе используется цикл для push_back () старых векторных элементов в новый вектор. Они глубоко копируются
using namespace std;
// Инициализация вектора со значениями
// Объявление нового вектора
// Цикл для копирования элементов
// старый вектор в новый вектор
// Изменение значения вектора, чтобы показать, что новый
В приведенном выше коде, при изменении значения в одном векторе не изменилось значение в другом векторе, следовательно, они не размещаются по одному и тому же адресу, следовательно, глубокое копирование.
Способ 2: с помощью оператора «=» .
Простое назначение нового вектора старому копирует вектор. Этот способ присвоения невозможен в случае массивов.
using namespace std;
// Инициализация вектора со значениями
// Объявление нового вектора
// Использование оператора присваивания для копирования одного
// вектор к другому
// Изменение значения вектора, чтобы показать, что новый
Способ 3: передавая вектор в качестве конструктора. Во время объявления вектора, передавая старый инициализированный вектор, копирует элементы переданного вектора во вновь объявленный вектор. Они глубоко скопированы.
using namespace std;
// Инициализация вектора со значениями
// Объявление нового вектора и копирование
// элемент старого вектора
// метод конструктора, глубокая копия
// Изменение значения вектора, чтобы показать, что новый
Способ 4: с помощью встроенных функций
-
copy (first_iterator_o, last_iterator_o, back_inserter ()) : — это еще один способ скопировать старый вектор в новый. Эта функция принимает 3 аргумента, во-первых, первый итератор старого вектора, во-вторых, последний итератор старого вектора и третья функция back_inserter для вставки значений из back. Это также
сгенерировал глубокую копию.
В этой статье объясняется несколько методов копирования объекта-контейнера std::vector в C++.
Использование нотации списка инициализаторов для копирования векторного объекта-контейнера в C++
std::vector - это основная структура данных, предоставляемая в библиотеке контейнеров STL. Он реализует массивы динамического размера, элементы которых хранятся непрерывно. Управление памятью выполняется автоматически, когда пользователь добавляет или удаляет элементы из массива. Мы можем сделать копию векторного объекта, используя нотацию списка инициализаторов при построении новой переменной типа std::vector . Обратите внимание, что нам просто нужно передать итераторы begin и end исходного векторного объекта, который необходимо скопировать в новый объект. Используя ту же нотацию, вы можете извлечь любой подвектор объекта, указав соответствующие итераторы в качестве аргументов в фигурных скобках.
Используйте алгоритм std::copy для копирования векторного объекта-контейнера в C++
Другой способ скопировать объект std::vector - вызвать функцию std::copy из библиотеки алгоритмов STL. Он обеспечивает общую операцию копирования для объектов на основе диапазона. Функция имеет несколько перегрузок, но перегрузка, используемая в следующем фрагменте кода, принимает три аргумента итератора. Первые два указывают исходный диапазон векторов, а третий итератор указывает начало диапазона векторов назначения.
Использование оператора присваивания копирования для копирования объекта-контейнера вектора в C++
В качестве альтернативы вы можете использовать оператор присваивания копии, чтобы скопировать содержимое объекта-контейнера std::vector . Эти обозначения - наиболее краткое решение данной проблемы. Нам просто нужно присвоить переменную исходного вектора вновь объявленному объекту вектора.
Использование конструктора копирования для копирования объекта-контейнера вектора в C++
С другой стороны, конструктор копирования класса std::vector предлагает аналогичный метод для копирования вектора во вновь объявленный векторный объект. В этом случае нам нужно передать переменную исходного вектора в круглые скобки при объявлении вновь созданной векторной переменной.
Используйте функцию-член assign для копирования векторного объекта-контейнера в C++
Контейнер std::vector предоставляет функцию-член assign , которую вы можете использовать для замены содержимого одного векторного объекта элементами другого вектора. Обратите внимание, что мы можем инициализировать пустой vector контейнер, а затем вызвать функцию assign из объекта, чтобы скопировать содержимое другого вектора.
Сопутствующая статья - C++ Vector
report this ad
В этой статье будет рассказано, как использовать конструктор перемещения в C++.
Использование конструктора перемещения для обеспечения эффективного управления копированием для классов в C++
Управление копированием класса определяет основные функции, необходимые для определения того, что происходит, когда объект класса копируется, перемещается, назначается или уничтожается. Эти функции имеют специальную номенклатуру C++, например, функции конструктора копирования и конструктора перемещения определяют, как объект инициализируется другим объектом того же типа. Функции копирования-назначения и перемещения-назначения определяют, как объект назначается одному и тому же типу объекта. Destructor обрабатывает процедуру, которая выполняется, когда объект выходит за пределы области видимости. Некоторые из этих функций, скорее всего, будут определены пользователем, но в противном случае компилятор сам создает прототипы по умолчанию.
Когда объект класса управляет динамической памятью, а данные довольно большие, операции копирования могут потребовать значительных вычислительных ресурсов. Они могут использовать значительные ресурсы, влияющие на производительность. Таким образом, они часто используют конструктор перемещения для переназначения динамических данных, не копируя их в новое место в памяти. Это достигается путем присвоения указателей старого объекта соответствующим членам вновь инициализированного или назначенного объекта. Обратите внимание, что следующий пример не включает конструктор перемещения и вызывает несколько вызовов конструктора копирования, который делегирует конструктору по умолчанию.
Как только мы определяем конструктор перемещения, который обычно должен принимать ссылку на r-значение в качестве первого аргумента (обозначенного обозначением && ), инициализация вектора становится более эффективной по мере добавления новых элементов типа MyClass . Поскольку конструктор перемещения не выделяет новую память и занимает место, занимаемое переданным объектом, необходимо присвоить nullptr членам предыдущего объекта. В противном случае деструктор дважды попытается освободить одну и ту же область памяти, что приведет к ошибке времени выполнения.
Сопутствующая статья - C++ Class
report this ad
Программирование и разработка
Чтобы понять концепцию конструктора копирования, вам нужно понять, какой конструктор является первым. В программировании конструктор называется методом-членом, вызываемым спонтанно, как только создается сущность или объект. С другой стороны, конструктор копирования — это своего рода конструктор или метод, который инициализирует сущность или объект через другой объект или сущность аналогичного класса.
Откройте и войдите в систему Ubuntu 20.04 Linux. Убедитесь, что в вашей системе Ubuntu 20.04 настроен компилятор C ++. Если нет, откройте терминал командной оболочки с помощью «Ctrl + Alt + T». Теперь сначала установите пакеты, необходимые для сборки, используя apt. Для его установки может потребоваться пароль вашей учетной записи sudo. Добавьте пароль и нажмите Enter. Используйте для этого следующий запрос:
После установки необходимых пакетов самое время установить компилятор языка C ++. Для этого используйте пакет apt для его установки. Используйте в оболочке следующий запрос:
Теперь проверьте установленную версию компилятора c ++ в вашей системе. Для этого используйте следующую команду версии.
Пример 1
Вы должны понимать, что только неглубокая копия может быть сделана с помощью стандартного метода конструктора копирования. Неглубокая копия описывается как создание дубликата объекта путем репликации всей или большей части информации о переменных компонента в их текущем состоянии. Чтобы увидеть иллюстрацию и работу неглубокой копии с помощью конструктора копирования, давайте начнем с примера. Прежде всего, создайте новый файл c ++, используя расширение «cc» и сенсорную команду. Команда выглядит следующим образом:
Откройте только что созданный файл » main.cc » в редакторе GNU, чтобы добавить в него код C ++, используя приведенный ниже код.
Теперь, когда файл открыт, напишите в нем приведенный ниже код. Сначала мы включили в код пакет стандартного потока ввода-вывода. Добавил пространство имен и создал класс «Тест». В этом классе мы определили переменные целочисленного типа x, y и z. Затем мы использовали метод конструктора, чтобы выделить некоторое пространство памяти для указателя z. Данные использовались для присвоения значений целым числам a, b и переменной-указателю z. Метод Show () использовался для печати значений, присвоенных переменным. Функция main используется для запуска компиляции кода. Мы создали единственный объект t1 для класса Test. Используя этот объект, мы передали некоторые значения функции «Данные». Затем мы использовали способ конструктора копирования, чтобы скопировать один конструктор в другой. Затем был вызван метод Show () с использованием второго объекта для печати значений целых чисел. Поскольку в примере ниже не указана функция Object (), фраза Demo t2 = t1; вызывает функцию компилятора по умолчанию Object (). Функция по умолчанию Object () создает глубокую или точную копию существующей сущности. В результате оба указателя объекта «z» относятся к одному и тому же адресу памяти. В результате, когда память одного поля освобождается, память другого поля также освобождается, поскольку оба поля связаны с одним и тем же адресным пространством. Сохраните файл с помощью Ctrl + S и закройте его, используя Ctrl + X, чтобы скомпилировать код. хранилище другого поля также освобождается, поскольку оба поля связаны с одним и тем же адресным пространством. Сохраните файл с помощью Ctrl + S и закройте его, используя Ctrl + X, чтобы скомпилировать код. хранилище другого поля также освобождается, поскольку оба поля связаны с одним и тем же адресным пространством. Также сохраните файл с помощью Ctrl + S и закройте его, используя Ctrl + X, чтобы скомпилировать код.
Скомпилируйте свой код C ++ в оболочке через компилятор g ++, как показано ниже.
Давайте выполним файл, чтобы увидеть результаты метода неглубокого копирования конструктора копирования. Для этого попробуйте следующий запрос:
Читайте также: