C++: библиотека программиста



Download 1,95 Mb.
Pdf ko'rish
bet29/144
Sana24.02.2022
Hajmi1,95 Mb.
#223123
TuriРеферат
1   ...   25   26   27   28   29   30   31   32   ...   144
Bog'liq
C -Eldjer-Djeff-for-Real-Programmers-RUS-www.itlibitum.ru


разделенные запятыми). 
2. Затем вызываются конструкторы переменных класса в порядке их объявления в объявлении 
класса. 
3. После того как будут сконструированы все базовые классы и переменные, выполняется тело 
вашего конструктора. 
Описанный порядок применяется рекурсивно, то есть первым конструируется первый базовый класс 
первого базового класса... и т. д. Он не зависит от порядка, указанного в списке инициализации членов. 
Если бы дело обстояло иначе, для разных перегруженных конструкторов мог бы использоваться 
разный порядок конструирования. Тогда компилятору было бы трудно гарантировать, что деструкторы 
будут вызываться в порядке, обратном порядку вызова конструкторов. 
Конструкторы копий 
Конструктор копий (copy constructor) определяется специальной сигнатурой: 
class Foo { 
public: 
Foo(const 
Foo&); 
}; 
Foo::Foo(const Foo& f)... 
Конструктор копий предназначен для создания копий объектов. Эта задача может возникнуть в самых 
разных обстоятельствах. 
void Fn(Foo f) {...} 
void Gn(Foo& f) {...} 
Foo f; 
Foo f1(f); 
Foo f2 = f; 
// Конструирование, а не присваивание! 
Fn(f); // 
Вызывает конструктор копий для передачи по назначению 
const Foo f3; 
Gn(f3);
// 
Конструктор копий используется 
// 
для создания неконстантной копии 
Давайте внимательно рассмотрим этот фрагмент. Строка 
Foo f1(f);
создает новый экземпляр класса 
Foo, передавая другой экземпляр класса 
Foo
в качестве аргумента. Это всегда можно сделать, если 


 36 
класс 
Foo
не содержит чисто виртуальных функций. Не важно, объявили ли вы свой собственный 
конструктор копий; если нет, компилятор построит его за вас. Не важно, есть ли в 
Foo
другие 
пользовательские конструкторы; в отличие от конструкторов без аргументов, конструктор копий 
доступен всегда. 
Строка 
Foo f2 = f
выглядит как присваивание из-за присутствия оператора 
=
, но на самом деле это 
альтернативный вариант вызова конструктора копий. Чтобы понять, чем присваивание отличается от 
инициализации, спросите себя: «Был ли объект сконструирован заранее или же его создание является 
частью команды?» Если объект уже существует, вы имеете дело с присваиванием. Если он создается на 
месте, как в пашем примере, используется конструктор копий. 
При вызове функции 
Fn()
происходит передача по значению копии 
Foo
. Конструктор копий 
используется для создания временной копии, существующей лишь во время выполнения 
Fn()
. После 
этого вызывается деструктор копии, который уничтожает ее. 
Вызов функции 
Gn()
, вероятно, ошибочен, и хороший компилятор прочитает вам суровую нотацию о 
стиле программирования на C++ — что-нибудь вроде: 
«Создается временная неконстантная копия — поучись программировать, тупица!» По крайней мере, 
со мной компиляторы обычно поступают именно так. Проблема заключается в том, что аргумент 
передается по ссылке, однако фактический аргумент является константным, а формальный — нет. Все 
изменения аргумента внутри 
Gn()
вносятся в копию, а не в оригинал. 
В создаваемом компилятором конструкторе копий по умолчанию используется строго определенная 
последовательность вызова конструкторов копий базовых классов и переменных класса. 
1. Конструкторы копий базовых классов вызываются в том порядке, в котором они объявлены в 
списке наследования. 
2. Конструкторы копий переменных вызываются в том порядке, в котором они объявлены в 
объявлении класса. 
Описанный порядок применяется рекурсивно, то есть первым копируется первый базовый класс 
первого базового класса... и т. д. Звучит знакомо, не правда ли? Тот же порядок, что и для любого 
другого конструктора. 
С конструкторами копий, в отличие от всех остальных, компилятор ведет себя гордо и ревниво. Если 
вы перегрузите конструктор копий для некоторого класса, компилятор, фигурально выражаясь, 
умывает руки и отправляется домой. При отсутствии явного вызова конструкторов копий базовых 
классов и переменных класса в списке инициализации членов вашего собственного конструктора 
копий компилятор будет использовать конструктор без аргументов для инициализации базовых 
классов и переменных. 
class Foo {...}; 
class Bar : public Foo { 
private: 
Foo 
f; 
public: 
Bar(const 
Bar&); 
}; 
// Вероятно, ошибка 
Bar::Bar(const Bar& b) 

// 
Стоп! Нет списка инициализации членов 
// 
Будут использованы конструкторы без аргументов 
// 
базового класса и переменной 

// Вероятно, ошибки нет 
Bar::Bar(const Bar& b) : Foo(b), f(b.f) {...} 



Download 1,95 Mb.

Do'stlaringiz bilan baham:
1   ...   25   26   27   28   29   30   31   32   ...   144




Ma'lumotlar bazasi mualliflik huquqi bilan himoyalangan ©hozir.org 2024
ma'muriyatiga murojaat qiling

kiriting | ro'yxatdan o'tish
    Bosh sahifa
юртда тантана
Боғда битган
Бугун юртда
Эшитганлар жилманглар
Эшитмадим деманглар
битган бодомлар
Yangiariq tumani
qitish marakazi
Raqamli texnologiyalar
ilishida muhokamadan
tasdiqqa tavsiya
tavsiya etilgan
iqtisodiyot kafedrasi
steiermarkischen landesregierung
asarlaringizni yuboring
o'zingizning asarlaringizni
Iltimos faqat
faqat o'zingizning
steierm rkischen
landesregierung fachabteilung
rkischen landesregierung
hamshira loyihasi
loyihasi mavsum
faolyatining oqibatlari
asosiy adabiyotlar
fakulteti ahborot
ahborot havfsizligi
havfsizligi kafedrasi
fanidan bo’yicha
fakulteti iqtisodiyot
boshqaruv fakulteti
chiqarishda boshqaruv
ishlab chiqarishda
iqtisodiyot fakultet
multiservis tarmoqlari
fanidan asosiy
Uzbek fanidan
mavzulari potok
asosidagi multiservis
'aliyyil a'ziym
billahil 'aliyyil
illaa billahil
quvvata illaa
falah' deganida
Kompyuter savodxonligi
bo’yicha mustaqil
'alal falah'
Hayya 'alal
'alas soloh
Hayya 'alas
mavsum boyicha


yuklab olish