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



Download 1,95 Mb.
Pdf ko'rish
bet35/144
Sana24.02.2022
Hajmi1,95 Mb.
#223123
TuriРеферат
1   ...   31   32   33   34   35   36   37   38   ...   144
Bog'liq
C -Eldjer-Djeff-for-Real-Programmers-RUS-www.itlibitum.ru

 
47 
Перегрузка операторов в форме внешних функций 
Чтобы перегрузить оператор в форме внешней функции, необходимо определить глобальную 
функцию. 
class String { 
friend String& operator+(const String&, const String&); 
private: 
char* 
s; 
public: 
// 
Конструкторы и т.д. 

String& operator+(const String& s1, const String& s2) 

char* s = new char[strlen(s1.s) + strlen(s2.s) + 1]; 
strcat(s, 
s1.s, 
s2.s); 
String 
newStr(s); 
delete 
s; 
return 
newStr; 

String s1 = “Hello”; 
String s2 = “Goodbye”; 
String s3 = s1 + s2; 
Перегруженная функция выглядит так же, как и любая глобальная функция (если не считать странного 
имени). Именно для таких случаев и были придуманы друзья. Если бы мы не объявили функцию 
operator+
другом, то она не имела бы доступа к переменной 
s
, и мы оказались бы перед выбором: то 
ли разрешить всем на свете доступ к 
char*
, то ли перейти к менее эффективной реализации, при кото-
рой строка копируется при каждом обращении к ней. С концептуальной точки зрения 
operator+
является частью библиотеки 
String
, поэтому нет ничего страшного в том, чтобы объявить эту 
функцию другом и вручить ей ключи к внутреннему устройству 
String

Внешними функциями могут перегружаться любые операторы, кроме операторов преобразования, 
=

[]

()
и 
->
— все эти операторы должны перегружаться только функциями класса. 
Перегрузка операторов в форме функций класса 
Синтаксис напоминает обычную перегрузку функций класса, разве что количество аргументов 
уменьшается на 1 по сравнению с формой внешней функции. 
class String { 
private: 
char* 
s; 
public: 
// 
Конструкторы и т.д. 
String& operator+(const String&) const; 
}; 
String& String::operator+(const String& s1) const 

char* s2 = new char[strlen(s1.s) + strlen(s) + 1]; 
strcat(s2, 
s1, 
s); 
String 
newStr(s2); 
delete 
s2; 
return 
newStr; 



 48 
String s1 = “Hello”; 
String s2 = “Goodbye”; 
String s3 = s1 + s2; 
Любой оператор может быть перегружен в форме функции класса. Если оператор может перегружаться 
как внешней функцией, так и функцией класса, какую из двух форм выбрать? Ответ: используйте 
перегрузку в форме функции класса, если только у вас не найдется веских причин для перегрузки 
внешней функцией. Из этих причин наиболее распространены следующие: 
1. Первый аргумент относится к базовому типу (например, 
int
или 
double
). 
2. Тип первого аргумента определен в коммерческой библиотеке, которую нежелательно 
модифицировать. 
Компилятор ищет перегрузку в форме функций класса, просматривая левую часть бинарных 
операторов и единственный аргумент унарных. Если ваш тип указывается справа и вы хотите 
воспользоваться перегрузкой в форме функции класса, вам не повезло. Самый распространенный 
пример перегрузки в форме внешней функции — оператор 
<<
в библиотеке ostream. 
ostream& operator<<(ostream& os, const String& s) 

os 
<< 
str.s; 
// 
Предполагается, что данная функция является другом 
return 
os; 

Перегрузка должна осуществляться в форме внешней функции, поскольку ваш тип, 
String
, находится 
справа — если, конечно, вы не хотите залезть в готовые заголовки iostream.h и включить в класс 
ostream
перегрузку в форме функции класса для своего класса 
String
. Наверное, все-таки не хотите. 
Примечание: предыдущий пример может не работать в вашем компиляторе, если функции 
strlen
и 
strcat
, как это часто бывает, по недосмотру разработчиков получают 
char*
вместо 
const char*

Вы можете решить, что игра не стоит свеч, и объявить функцию неконстантной, но это выглядит 
слишком жестоко. Лучше избавиться от константности посредством преобразования типов, если вы 
абсолютно уверены, что библиотечная функция не модифицирует свои аргументы, и готовы смириться 
с предупреждениями компилятора. 
String& String::operator+(const String& s1) const 

char* s2 = new char[strlen((char*)s1.s) + strlen(s) + 1]; 
strcat(s2, 
(char*)s1.s, 
s); 
String 
newStr(s2); 
delete 
s2; 
return 
newStr; 

Видите, что происходит, если кто-то забывает о константности? 
Операторы преобразования 
Оператор преобразования — особый случай. Если конструктор представляет собой отображение 
аргументов на домен вашего класса, то оператор преобразования делает прямо противоположное: по 
экземпляру вашего класса он создает другой тип данных. 
class String { 
private: 
char* 
s; 
public: 
operator 
long(); 
// 
Использует atol для преобразования к типу long 
}; 
String::operator long() 



Download 1,95 Mb.

Do'stlaringiz bilan baham:
1   ...   31   32   33   34   35   36   37   38   ...   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