Файл: Pobegaylo_A._C_Cplus_dlya_studenta.pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 13.12.2020

Просмотров: 4308

Скачиваний: 28

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Часть II. Язык программирования С++ 

216 

  Demo* operator ->() const { return p; } 
  Demo* operator &() const { return p; } 
  Demo& operator *() const { return *p; } 
}; 
int main() 

  Demo d = {0}; 
  ptr p(d); 
 
  (*p).n += 10; 
  cout << (&p)->n << endl;    // печатает 10 
  cout << p->what() << endl;  // печатает 10 
 
  return 0; 

16.8. Операторы инкремента  

и декремента 

Операторы  инкремента  и  декремента  могут  быть  перегружены 
как члены класса без аргументов или как не члены класса с одним 
аргументом.  Для  того  чтобы  префиксные  операторы 

++

  и 

--

  от- 

личать от соответствующих постфиксных операторов, в объявле-
нии последних вводят дополнительный фиктивный параметр ти-
па 

int

В  листинге  16.6  приведен  пример  перегрузки  префиксного  и 
постфиксного операторов инкремента. 

Листинг 16.6. Перегрузка префиксного и постфиксного операторов 
инкремента 

#include <iostream> 
using namespace std; 
class Count 

  int n; 
public: 
  Count(int _n): n(_n) {} 


background image

Глава 16. Перегрузка операторов 

217 

  Count& operator ++()    // префиксный ++ 
  { 
    ++n; 
    return *this; 
  } 
  Count operator ++(int)  // постфиксный ++ 
  { 
    ++n; 
    return Count(n - 1); 
  } 
  int get() { return n; } 
}; 
 
int main() 

  Count c(0); 
  cout << ((++c)++).get() << endl;  // печатает 1 
  cout << c.get() << endl;          // печатает 2 
 
  return 0; 
}

 

16.9. Бинарные операторы 

Бинарные операторы могут быть перегружены как нестатические 
члены класса с одним параметром: 

  тип operator @(параметр); 

Или как операторы не члены класса с двумя параметрами. 

  тип operator @(параметр_1, парметр_2); 

Символ 

@

 обозначает один из следующих бинарных операторов: 

  +  -  *  .  %  ==  <=  >=  !=  &&  ||  <<  >> 

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


background image

Часть II. Язык программирования С++ 

218 

Например, для класса 

Bool

 оператор сравнения на равенство сле-

дует перегрузить следующим образом: 

Bool operator ==(const Bool& b1, const Bool& b2) 

  return Bool(b1.n ? (b2.n ? 1 : 0) : (b2.n ? 0 : 1)); 

Если  же  оператор  сравнения  на  равенство  будет  определен  как 
член класса, то первый параметр этого оператора будет иметь тип 

const Bool* const

, а второй параметр — тип 

const Bool&

, что на-

рушает  симметричность  параметров  и  требует  дополнительного 
преобразования типов. 

16.10. Перегрузка операторов 

>>

 и 

<<

 

для ввода и вывода 

Перегруженные операторы ввода/вывода 

>>

 и 

<<

 должны опреде-

ляться как дружественные операторы класса, которые имеют сле-
дующий прототип: 

  friend istream& operator >>(istream&, имя_класса&); 
  friend ostream& operator <<(ostream&, const имя_класса&); 

Это  позволяет  избежать  путаницы  с  общепринятым  написанием 
этих операторов. Например, перегрузим операторы 

>>

  и 

<<

  соот-

ветственно для ввода и вывода данных типа 

Bool

std::istream& operator >>(std::istream& in, Bool& b) 

  in >> b.n; 
  b.n ? b.n = 1 : b.n = 0; 
  return in; 

std::ostream& operator <<(std::ostream& out, const Bool& b) 

  return out << b.n; 


background image

Глава 16. Перегрузка операторов 

219 

Теперь эти операторы можно использовать следующим образом: 

  Bool a; 
 
  cin >> a; 
  cout << a << endl; 

16.11. Операторы преобразования 
типов (конвертеры) 

Конвертер

 — это функция-член класса, которая преобразует тип 

объекта  класса  в  некоторый  другой  тип.  Конвертер  имеет  сле-
дующий прототип: 

  operator тип(); 

Здесь 

тип

 задает тип данных, к которому приводится объект. Этот 

тип может быть как встроенным типом данных, так и типом дан-
ных, определенным пользователем. Конвертер может вызываться 
как явно, так и неявно — при преобразованиях типов данных. 
Например,  определим  для  класса 

Bool

  оператор  преобразования 

в тип 

bool

  Bool::operator bool(void) const { return n ? true : false; } 

После  определения  этого  оператора  значения  типа 

Bool

  можно 

использовать в выражениях со значениями типа 

bool

. Например: 

  bool a; 
  Bool b = 0; 
 
  a = true && b;  // а = false 

16.12. Операторы 

new

 и 

delete

 

Перегрузка  операторов 

new

  и 

delete

  не  подчиняется  общим  пра-

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

static

 не используется. Перегруженные операторы 

new

 и 


background image

Часть II. Язык программирования С++ 

220 

delete

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

ливы и для перегруженных операторов 

new[]

 и 

delete[]

Перегруженный  оператор 

new

  должен  иметь  следующий  прото-

тип: 

  [static] void* operator new(size_t[, параметры]); 

То  есть  перегруженный  оператор 

new

  должен  возвращать  значе-

ние типа 

void*

  и  его  первый  параметр  должен  иметь  тип 

size_t

Значение  первого  параметра  передается  перегруженному  опера-
тору 

new

  средой  исполнения  неявно  и  содержит  размер  памяти, 

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

new

 явно. 

В прототипе перегруженного оператора 

new

 можно также указать 

спецификацию выбрасываемых этим оператором исключений. 
Перегруженный  оператор 

delete

  должен  иметь  следующий  про-

тотип: 

  [static] void operator delete(void*[, параметры]); 

То  есть  перегруженный  оператор 

delete

  не  должен  возвращать 

значения и его первый параметр должен иметь тип 

void*

. Значе-

ние  первого  параметра  передается  перегруженному  оператору 

delete

  явно  и  должно  содержать  адрес  памяти,  предварительно 

распределенной для объекта перегруженным оператором 

new

. По-

сле первого параметра могут следовать другие параметры. 
В прототипе перегруженного оператора 

delete

 можно также ука-

зать  спецификацию  выбрасываемых  этим  оператором  исклю- 
чений. 
В  листинге  16.7  приведен  пример  перегрузки  операторов 

new

  и 

delete

 как членов класса. 

Листинг 16.7. Перегрузка операторов 

new

 

и 

delete

 

#include <iostream> 
#include <cstdlib> 
using namespace std; 


Смотрите также файлы