Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

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

Применение конструкторов копирования и преобразования

Рассмотрим специальные свойства конструкторов, имеющих единственный параметр. Это – конструкторы с дополнительными параметрами и стандартными значениями, которые, следовательно, могут быть вызваны с единственным параметром. Если единственный (или первый) параметр является ссылкой на тот же тип данных, что и класс, то конструктор называется конструктором копирования. Если же параметр имеет тип, отличающийся от класса конструктора, то такой конструктор называется конструктором преобразования.

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

CTest (int Farm) { // код конструктора... }

то можно создать объект, используя оператор

CTest Test (5);

или эквивалентный оператор

CTest Test = 5;

Использование знака равенства – альтернативный способ передачи единственного значения конструктору. Это операция инициализации, а не присваивания, поэтому перегрузка оператора «=» не влияет на выполнение данной операции.

Конструктор копирования класса – это конструктор с единственным параметром, тип которого определен как ссылка на тип класса.

class CTest{ //... public CTest (const CTest &Test) { // использует члены объекта Test для инициализации // нового объекта класса CTest... } //...}

Далее будет показано, почему параметр должен быть ссылкой на объект, а не самим объектом.

Если конструктор копирования класса не определен, то компилятор генерирует его неявно. Конструктор, генерируемый компилятором, инициализирует новый объект, выполняя операцию поэлементного копирования переменных существующего объекта класса, передаваемого как параметр. Соответственно, используя объект того же типа, всегда можно инициализировать его, даже если конструктор копирования в классе не определен. Например, даже если класс CCurrency, рассмотренный ранее, не содержит конструктор копирования, то следующая инициализация все равно будет корректной:

CCurrency Money1 (95, 34);CCurrency Money2 (Money1); CCurrency Моnеу3 = Money1;

Инициализация объекта Моnеу2, как и Моnеу3, вызывает конструктор копирования, сгенерированный компилятором. В результате данной инициализации оба объекта (Money2 и Моnеу3) будут содержать те же значения, что и Moneyl (т.е. переменная Dollars будет равна 95, a Cents – 34).

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

class CMessage{ //... public: CMessage {const CMessage &Message) { Buffer = new char [strlen (Message.Buffer) + I]; strcpy (Buffer, Message.Buffer); } //... };

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

CMessage Message1;Message1.Set ("hello");CMessage Message2 (Message1); // используется конструктор копирования CMessage Message3 = Message1; // используется конструктор копирования

Также компилятор автоматически вызывает конструктор копирования класса в следующих двух случаях: при передаче объекта класса в качестве параметра функции и при возврате функцией объекта класса. Рассмотрим функцию-оператор.

CCurrency operator+ (CCurrency Curr) { return CCurrency (Dollars + Curr.Dollars, Cents + Curr.Cents); }

Параметр Curr является объектом класса CCurrency. При каждом вызове функции он должен создаваться и инициализироваться с помощью объекта, передаваемого в функцию. Для инициализации параметра компилятор инициализирует вызов конструктора копирования, определенного явно или сгенерированного компилятором.

Примечание

Так как компилятор вызывает конструктор копирования каждый раз при передаче объекта класса в функцию, объект класса нельзя передавать как первый параметр в сам конструктор копирования. Напротив - необходимо передать ссылку на него. Передача объекта (если компилятор разрешит) послужит причиной бесконечной рекурсии.

Поскольку тип значения, возвращаемого функцией, является объектом класса CCurrency, то при вызове функции компилятор генерирует временный объект класса CCurrency и использует значение, определенное в операторе return, для инициализации этого объекта. Для выполнения инициализации компилятор также вызовет конструктор копирования.

Совет

Непроизводительные издержки при вызове конструктора копирования можно исключить передачей и возвратом ссылок на объекты вместо самих объектов (если это возможно). Функция operator+, рассмотренная выше, не может возвращать ссылку на временный объект класса CCurrency. Передача ссылки на объект, который перестает существовать после выхода из функции, является плохим стилем программирования.

<== предыдущая лекция | следующая лекция ==>
Перегрузка оператора присваивания | Конструкторы преобразования
Поделиться с друзьями:


Дата добавления: 2014-01-07; Просмотров: 311; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.01 сек.