|
|||||||
АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомДругоеЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция |
Конструктор копирования
Class test { Int I; Public: Test() { cout<<"default"<<endl; I=1; } Int getI() { return i;} Void setI(int i0) {i=i0; } }; Void main() {test a, b=a; B.setI(b.getI()+1); Cout<<b.getI(); } В этой программе конструктор без параметров будет вызван 1 раз, для создания объекта a. Последняя печать показывает, что у объекта b поле I хранит значение 2. Можно убедиться, что у объекта a оно равно 1. Для создания любого объекта должен быть вызван конструктор. Так как b и a хранят разные значения поля i, то это два разных объекта. А конструктор для b не вызывался. Это возможно, потому что компилятор помимо конструктора без параметров создает еще 1 тип конструктора для инициализации объектов другими объектами того же класса. В данном случае объект b инициализируется объектом a того же класса test. Этот конструктор называется конструктором копирования. В простых случаях компилятор выполняет копирование каждого поля из одного объекта в другой. При инициализации объекта b объектом a копируется поле i со значением единицы. В тех случаях, когда программиста не устраивают действия конструктора копирования по умолчанию, можно написать свой вариант. Test(const test& t) Особенность конструктора копирования в том, что его первый аргумент всегда ссылка на объект своего класса. Можно запретить изменять объект при помощи const. При необходимости у конструктора копирования могут быть еще и другие параметры. Конструктор копирования вызывается: 1) при явной инициализации с помощью объекта данного класса: test a, a=b; 2) при вызове функции, у которой аргумент имеет тип данного класса: void f(test t) {}; f(b); t будет инициализироваться b. 3) Когда функция возвращается объект данного класса: test f(test t({ Return t;} В этом случае для временного хранения возвращаемого значения создается переменная, которая будет инициализироваться значением возвращаемого объекта. Пример необходимости создания своего конструктора копирования: Class string1 { Unsigned size; Char *p; Public: String1(char s[]) { P=new char[size=strle(S)+1]; Strcpy(p, S); } ~string1(){delete [ ] p;} }; Void main() { ... String1 s1("str"); { String1 s2=s1; } // переменная s2 будет существовать, пока мы не достигнем этой скобки. При выходе из блока, отработает деструктор, который освободит память, занятую строкой. Объект s1 будет также существовать. ... } Рассмотрим подробнее s2=s1; Будет вызван конструктор копирования по умолчанию. В результате s2.p будет хранить тот же адрес, что и s1.p. Когда отрабатывает деструктор для s2, освобождается память, которая еще используется s1. Чтобы не было этой ошибки нужно в программу добавить конструктор копирования, который будет выделять память для новой копии строки помещать туда эту строку: String1(string1&S) { P=new char[s.size+1]; Strcpy(p, s.p); } Поиск по сайту: |
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Студалл.Орг (0.003 сек.) |