|
|||||||
Время создания: 13.08.2015 01:25
Текстовые метки: c++, конструктор копирования, пример
Раздел: Компьютер - Программирование - Язык C++ (Си++)
Запись: xintrea/mytetra_syncro/master/base/1439414710chs6b1xcrf/text.html на raw.github.com
|
|||||||
|
|||||||
Конструктор копирования Продолжая начатую тему Конструктор копирования, я приведу пример случая, в котором необходимо создании конструктора копирования. Пример почти такой же, как в википедии куда я ранее ссылался, но чуть проще и немного понятнее для новичков в программировании. Внимание! Не следует путать конструктор копирования и реализацию оператора присваивания (operator=), это разные вещи! Зачем нужен конструктор копирования Вначале нужно показать код: #include <iostream.h> #include <stdlib.h> /*СТРУКТУРА МАССИВ*/ struct Array { int *element; //Указатель на int Array(int N); //Конструктор структуры, принимающий параметр типа int ~Array(); //Деструктор структуры для освобождения памяти }; Array::Array(int N) //Описываю конструктор вне структуры { element=new int[N]; //При каждом новом вызове будет выделяться новый участок памяти размером согласно принимаемому параметру }
Array::~Array() //Описываю деструктор вне структуры { delete []element; //Освобождаю память, выделенную внутри конструктора }
int main() { system("CLS"); Array v(3); //Объявляю переменную v, тип которой наша структура и выделяю память для 3 элементов int v.element[0]=20; //Записываю в переменную v значения v.element[1]=30; v.element[2]=40;
Array x=v; //Объявляю переменную x, тип которой наша структура и копирую туда данные из v cout<<x.element[0]<<" "<<x.element[1]<<" "<<x.element[2]<<endl; //Вывожу на экран элементы x
v.element[0]=100; //Например, появилась необходимость изменить объект v cout<<x.element[0]<<" "<<x.element[1]<<" "<<x.element[2]<<endl; //Вывожу на экран элементы x
cin.get(); return 0; } Если вы плохо знакомы с указателями, то выполнение этого кода может произойти слегка не так, как вы ожидали. Несмотря на то, что и в первом и во втором случае, я вывожу на экран только данные второго созданного мною объекта, не изменяя его напрямую, данные в нем изменились после изменения данных в первом объекте. Такое поведение работы программы объясняется тем, что срабатывает конструктор копирования по умолчанию. Этот конструктор копирования копирует указатель как указатель и получается, что в обоих объектах оба указателя указывают на один и тот же адрес. То есть если изменить данные, расположенные на том адресе, то и первый и второй объект будут получать те измененные данные. Думаю, суть вы должны уловить. Вот в таких случаях и возникает вопрос безопасного копирования данных из одного объекта в другой. Безопасное копирование в этом случае обозначает, что изменения одного из объектов не должны влиять на другой объект. Для решения этого вопроса как раз и используют конструктор копирования. Код с конструктором копирования #include <iostream.h> #include <stdlib.h> /*СТРУКТУРА МАССИВ*/ struct Array { int *element; //Указатель на int int size; //Размер массива Array(int N); //Конструктор принимает параметр, по которому определяет количество элементов для массива Array(Array &obj); //Конструктор копирования ~Array(); //Деструктор для освобождения памяти }; Array::Array(int N) //Описываю конструктор с параметром типа int вне класса { element=new int[N]; //При каждом новом вызове выделяю память для N элементов типа int size=N; //Запоминаю размер согласно указанному параметру } Array::Array(Array &obj) //Описываю конструктор копирования вне класса { element=new int[obj.size]; //Выделяю память для элемента объекта for (int i=0;i<obj.size;i++) element[i]=obj.element[i]; //Поэлементно копирую каждый элемент из принимаемого объекта в текущий size=obj.size; //скопировать нужно каждый кусочек класса, сами они не копируются } Array::~Array() //Описываю деструктор вне класса { delete []element; //Освобождаю память } int main() { system("CLS"); Array v(3); //Объявил объект v и указал, что он содержит три элемента v.element[0]=20; //Записал данные в объект v.element[1]=30; v.element[2]=40; Array x=v; //Объявляю второй объект и копирую в него данные из первого cout<<x.element[0]<<" "<<x.element[1]<<" "<<x.element[2]<<endl; //Вывожу данные второго объекта на экран v.element[0]=100; //Меняю одно поле первого объекта cout<<x.element[0]<<" "<<x.element[1]<<" "<<x.element[2]<<endl; //Вывожу данные второго объекта на экран
cin.get(); return 0; } В самый конец вы можете дописать вывод данных первого объекта на экран. В этом коде был использован прием, благодаря которому каждый объект будет обладать своим уникальным указателем. В первом случае была проблема в том, что оба указателя указывают на одно и то же место, значит, чтобы решить проблему, нужно сделать два указателя, которые не будут зависимы друг от друга и будут указывать на разные адреса. Кроме этого нужно учитывать, что при копировании размеры объектов должны совпадать. Чтобы размеры объектов совпадали, я при выделении памяти взял размер из принимаемого объекта и выделил столько памяти, сколько выделено для принимаемого объекта. Не нужно забывать, что при явном использовании конструктора копирования, выполнение копирования наша забота, поэтому копируем необходимые данные своими силами. Я выполнил поэлементное копирование одного массива в другой. После выполнения таких не хитрых операций легко можно работать с обоими объектами, не беспокоясь за то, что изменяя один объект мы навредим внутри другого. Это и есть ответ на вопрос: “Зачем нужен конструктор копирования” Я натыкался на примеры с деструкторами, но мне такие примеры давали больше воды, чем пользы. Такой пример немного нагляднее, понятнее и самое главное хорошо дает понять основные причины использования конструктора копирования. Но примеры ориентированные на деструкторы тоже полезны и нужны |
|||||||
Так же в этом разделе:
|
|||||||
![]() |
|||||||
|
|||||||
|