Студопедия

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

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

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






Конструкторы копирования






Конструктор копирования создает объект класса, копируя при этом данные из уже существующего объекта данного класса. В связи с этим он имеет в качестве единственного параметра константную ссылку на объект класса (const Т&) или просто ссылку на объект класса (Т&). Использование первого пред­почтительнее, так как последний не позволяет копировать константные объекты.

Ссылка передается всякий раз, когда новый объект инициализируется значениями существующего объекта. Если вы не предусмотрели конструктор копирования, компилятор генерирует конструктор копи­рования по умолчанию. В C++ различают поверхностное и глубинное копирование данных.

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

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

Если в классе не определен конструктор, компилятор пытается сгенерировать собственный конструк­тор по умолчанию и, если нужно, собственный конструктор копирования. Эти сгенерированные компиля­тором конструкторы рассматриваются как открытые функции-члены. Подчеркнем, что компилятор генери­рует эти конструкторы, если в классе не определен никакой другой конструктор.

Приведём пример использования конструктора копирования:
class Dot // класс точки

{

// закрытые члены класса

// имя точки // координаты точки // открытые члены класса

char name; double x, y; public:

// конструкторы с параметрами

Dot (char Name, double X, double Y) { name = Name; x = X; y = Y; }

Dot (char Name): name(Name), x (0), y (0) { }

Dot (char Name, const Dot& A) { name = Name; x = A.x; y = A.y; }

// конструктор копирования

Dot (const Dot& A) { name = (char) 226; x = A.x; y = A.y; }

void Print (); // выводит на экран имя и координаты текущей точки

};

void main ()

{

// вызов конструктора Dot (char Name, double X, double Y) // вызов конструктора Dot (char Name)

Dot A ('A', 3, 4); Dot B ('B');


Dot C (A); C.Print ();


// вызов конструктора копирования Dot (const Dot& A)

// выводит на экран: Координаты точки т: x=3 y=4


 


Dot D = B; D.Print ();


// вызов конструктора копирования Dot (const Dot& A)

// выводит на экран: Координаты точки т: x=0 y=0


Dot E ('E', A); E.Print ();

// вызов конструктора Dot (char Name, const Dot& A)

// выводит на экран: Координаты точки E: x=3 y=4

}

Конструктор копирования по умолчанию выполняет поверхностное копирование, которое в нашей за­даче копирует не только координаты, но и имена точки. Хотя наш объект не содержит динамических чле-



Объектно-ориентированное программирование


Лекция 3


Функции-члены класса



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

В приведённом примере точки С и D объявлены с помощью конструктора копирования объявленного нами. В этом конструкторе имя точки инициализируется фиксированным значением - русской буквой “ т ”.

Для решения этой задачи в приведённом примере объявлен конструктор:

Dot (char Name, const Dot& A) { name = Name; x = A.x; у = A.y; },

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






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